Java并发编程——线程带来的风险

在并发中有两种方式,一是多进程,二是多线程,但是线程相比进程花销更小且能共享资源。

多线程将会带来几个问题:

  一、安全性问题。

    线程安全性可能是非常复杂的,多线程中的操作执行顺序是不可预测的,甚至会产生奇怪的结果,另外由于存在指令重排序的可能,因此实际情况会很糟糕。

    有一种常见的并发安全问题叫“竞态条件”。由于多个线程要共享相同的内存地址空间,并且是并发运行,因此它们可能会访问或修改其他线程正在使用的变量。这带来的极大的便利,但是也有巨大的风险:线程会由于无法预料的数据变化而发生错误。当多个线程同时访问和修改相同的变量时,将会在串行编程模型中引入非串行因素,而这种非串行性是很难分析的。要使多线程程序的行为可预测,必须对共享变量的访问操作进行协同,这样才不会在线程之间发生彼此干扰。

    例如使用 synchronized 关键字来同步;

    public class Value {

        @GuardedBy("this") private int value;

        public synchronized int getNext(){

          return value++;

        }

    }

    @GuardedBy(lock)  指明对象或变量受哪个锁保护

 

  二、活跃性问题

    线程会导致一些在单线程程序中不会出现的问题,那就是活跃性问题。

    自己的理解的“活跃性问题”:即线程的活跃性,线程能够有意义的在正常的按设计工作。

    安全性问题的含义是“永远不发生糟糕的事情”,而活跃性则关注另外一个目标:“某件正确的事情最终会发生”。当某个操作无法继续执行下去时,就会发生活跃性问题。在串行程序中,活跃性问题的一种就是无意中造成的无限循环,使得不能按照设计的工作进行,执行不到后面的代码。或者由于资源竞争而导致的死锁等。

    活跃性问题同安全性问题同样难以分析,因为依赖于不同线程的事件发生时序,在测试中不总是能够重现。

 

  三、性能问题

    活跃性意味着某件正确的事情会中会发生,但却不够好,因为我们希望正确的事情尽快发生。性能问题包括多个方面,例如服务时间过长,响应不灵敏,吞吐率过低等等。

    所以多线程需要良好的设计来提升线程的性能,但无论如何线程总会带来额外的开销,由于多线程之间的调度会频繁地出现上下文切换操作,保存和恢复执行上下文,线程之间共享数据时需要同步等等。

 

  要做好并发应用程序就必须时刻注意和避免以上的问题,对于并发的学习还有很多东西需要了解学习。

    

posted on 2012-10-09 15:34  Boing Tan  阅读(475)  评论(0)    收藏  举报

导航