• 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     }
  • 相关阅读:
    java8泛型
    Java中各种引用(Reference)解析
    java8中字符串常量以及GC相应处理机制
    apache ignite系列(九):ignite调优
    CentOS7上OpenResty安装
    windows安装mingw和LuaJIT
    golang中Array与Slice
    apache ignite系列(九):使用ddl和dml脚本初始化ignite并使用mybatis查询缓存
    11-4 索引
    11-3 数据库的用户管理和pymysql模块的使用
  • 原文地址:https://www.cnblogs.com/alala666888/p/2694987.html
Copyright © 2020-2023  润新知