进行多线程并发程序,应该注意那些方面?

来源:互联网 发布:贵阳人口流入数据 编辑:程序博客网 时间:2024/05/13 17:21
编写并发的程序时应注意以下问题:
(1)、线程的优先级:线程的优先级代表该线程的重要程度,当有多个线程同时处于可执行状态并等待获得 CPU 时间时,线程调度系统根据各个线程的优先级来决定给谁分配 CPU 时间,优先级高的线程有更大的机会获得 CPU 时间,优先级低的线程也不是没有机会,只是机会要小一些罢了。
(2)、线程的阻塞:阻塞指的是暂停一个线程的执行以等待某个条件发生(如某资源就绪),在Java中人为的对线程进行阻塞时,应注意避免产生死锁。
(3)、同步对象的恒定性:不要对同步对象重新赋值,举个例子:
           class A implements Runnable{
      Object lock = new Object();

      void run(){
        for(...){
        synchronized(lock){
          // do something
      ...
      lock = new Object();
        }
      }
    }
run函数里面的这段同步代码实际上是毫无意义的。因为每一次lock都给重新分配了新的对象的reference,每个线程都在新的reference同步。所以,一般应该把同步对象声明为final.
    final Object lock = new Object();
使用Singleton Pattern 设计模式来获取同步对象,也是一种很好的选择。
(4)、跨类的同步对象:但是对于复杂的问题,我们需要把问题分为几个部分来处理,需要几个不同的类来处理问题。这时,就需要在不同的类中,共享同步对象。比如,在生产者和消费者之间共享同步对象,在读者和写者之间共享同步对象。
如何在不同的类中,共享同步对象。有几种方法实现,
       1、前面讲过的方法,使用static静态成员,(或者使用Singleton Pattern.)
       2、用参数传递的方法,把同步对象传递给不同的类。
       3、利用字符串常量的“原子性”。
对于第三种方法,这里做一下解释。一般来说,程序代码中的字符串常量经过编译之后,都具有唯一性,即,内存中不会存在两份相同的字符串常量。
(5)、同步的粒度:线程同步的粒度越小越好,即,线程同步的代码块越小越好。尽量避免用synchronized修饰符来声明方法。尽量使用synchronized(anObject)的方式,如果不想引入新的同步对象,使用synchronized(this)的方式。而且,synchronized代码块越小越好。

原创粉丝点击