java并发1--线程间同步

    线程间同步说的通俗一点讲就是两点:
          1. 当某个线程处理好数据后能通知其他线程自己活干完了,然后别的线程能使用它处理好的数据做其他事情。(Object.notify, Object.notifyAll)
          2. 某个线程需要其他线程的计算结果时,需要等待知道别的线程把活干完了,它拿到数据开始干自己的活。(Object.wait)

    java对并发的支持很全面,而且直接在基类Object里面提供了支持,最常用的三种方法列举如下(上面其实已经提到了):
          1. Object.notify:通知某个线程自己活干好了,兄弟可以开工了。某个调用了此对象的wait方法的线程将停止阻塞,返回。
          2. Object.notifyAll:通知所有线程自己活干好了。所有调用了此对象wait方法的线程都将停止阻塞,返回。
          3. Object.wait:等待其它线程活干完了,自己再开工。此方法将阻塞,直到某个线程调用了notify或者notifyAll为止。

 

    下面是个简单的例子,例子的用意是三个线程A、B、C一起干活,每一次工序需要A先干完然后B开工,B干完然后C开工,然后进入下一个工序、如此反复。
    流程图:
    

    

Java代码
 1 /** 
 2      * 并发打印类
 3      * @author shun.li
 4      */
 5     static class ConcurrentPrinter implements Runnable 
 6     {
 7         
 8         //线程互斥变量
 9         private static Object mutex = new Object();
10         //当前获得打印资格的线程的名字
11         private static String currentName = "";        
12         public static void setCurrentName(String name) {
13             currentName = name;
14         }
15         
16         private String name;        //本线程名字
17         private String nextName;//下一个可打印的线程名
18         private int count;            //打印次数
19         
20         public ConcurrentPrinter(String name, String nextName, int count) {
21             this.name = name;
22             this.nextName = nextName;
23             this.count = count;
24         }
25         
26         /**
27          *  打印信息,打印次数为
28          */
29         public void print() {
30             //:打印互斥,各个线程只有一个打印完了下一个才可以开始
31             synchronized(mutex) {
32                 
33                 //:等待上一个线程通知自己可以打印
34                 while(currentName != name) {
35                     try {
36                         mutex.wait();
37                     } catch (InterruptedException e) {                        
38                         return;
39                     }
40                 }
41                 //:打印
42                 for(int i = 0; i < count; ++i) {
43                     System.out.println(String.format("%1$04d:%2$s",i,name));
44                 }
45                 //设置可执行线程名为下一个
46                 currentName = nextName;
47                 //通知所有线程,名为currentName的线程符合条件,将开始打印
48                 mutex.notifyAll();
49             }                
50         }
51 
52         @Override
53         public void run() {
54             //各个线程先后执行打印任务100次
55             for(int i = 0; i < 10; ++i) {
56                 this.print();
57             }
58         }
59     }
60 
61     /**
62      * @param args
63      * @throws IOException 
64      */
65     public static void main(String[] args) {
66             System.out.println("alala");    
67             
68             //:创建3个线程,轮流打印
69             Thread aThread = new Thread(new ConcurrentPrinter("A","B",3));
70             Thread bThread = new Thread(new ConcurrentPrinter("B","C",3));
71             Thread cThread = new Thread(new ConcurrentPrinter("C","A",3));
72             ConcurrentPrinter.setCurrentName("A");
73             aThread.start();
74             bThread.start();
75             cThread.start();    
76     }
posted @ 2012-09-20 12:37  李土鳖  阅读(251)  评论(0编辑  收藏  举报