zoukankan      html  css  js  c++  java
  • 多线程循环打印ABC

    主要是利用线程的wait()和notify()来实现

    public class MyThread implements Runnable {
        private String name;
        private Object prev;
        private Object mine;
        
        private MyThread(String name,Object prev,Object mine){
            this.name = name;
            this.prev = prev;
            this.mine = mine;
        }
        
    
        @Override
        public void run() {
            int count = 10;
            while(count > 0){
                synchronized (prev) {
                    synchronized (mine) {
                        System.out.println(name);
                        count--;
                        mine.notify();
                    }
                    
                    try {
                        prev.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    
                }
            }
            
        }
        
        
        public static void main(String[] args) {
            Object a = new Object();
            Object b = new Object();
            Object c = new Object();
            MyThread pa = new MyThread("A", c, a);
            MyThread pb = new MyThread("B", a, b);
            MyThread pc = new MyThread("C", b, c);
            new Thread(pa).start();
            new Thread(pb).start();
            new Thread(pc).start();
            
        }
    
    }

    整理下程序的思路:因3个线程要按照顺序打印ABC,那么应该是ThreadA->ThreadB->ThreadC->ThreadA如此循环,当运行ThreadA时,prev对象是c,mine对象是a,打印A,然后唤醒线程a,最后让当前线程c等待,则ThreadA进入等待(注意此时调用的prev.wait()虽然让线程进入了等待,但同时也释放了对象的锁,其他线程可以访问此同步方法)。ThreadB的prev对象是a,mine对象是b,打印B;而ThreadC的prev对象是b,mine对象是c;其实这种方式不一定能完全保证是ABC的顺序输出,因为看程序,B线程在等待a对象的锁,获取a的锁才能继续向下进行,而C线程在如果抢先运行的话,b的锁是不需要等待的,则直接等待a的锁,在ThreadA运行完毕释放锁后,若C线程率先获取a的锁的话,那么打印顺序就会遭到改变。所以若要让线程A、B、C按照顺序执行的话,一定要让3个线程按照顺序执行。更改程序为:

     1 public class MyThread implements Runnable {
     2     private String name;
     3     private Object prev;
     4     private Object mine;
     5     
     6     private MyThread(String name,Object prev,Object mine){
     7         this.name = name;
     8         this.prev = prev;
     9         this.mine = mine;
    10     }
    11     
    12 
    13     @Override
    14     public void run() {
    15         int count = 10;
    16         while(count > 0){
    17             synchronized (prev) {
    18                 synchronized (mine) {
    19                     System.out.println(name);
    20                     count--;
    21                     try {
    22                         Thread.sleep(1);
    23                     } catch (InterruptedException e) {
    24                         e.printStackTrace();
    25                     }
    26                     mine.notify();
    27                 }
    28                 
    29                 try {
    30                     prev.wait();
    31                 } catch (InterruptedException e) {
    32                     e.printStackTrace();
    33                 }
    34                 
    35             }
    36         }
    37         
    38     }
    39     
    40     
    41     public static void main(String[] args) {
    42         Object a = new Object();
    43         Object b = new Object();
    44         Object c = new Object();
    45         MyThread pa = new MyThread("A", c, a);
    46         MyThread pb = new MyThread("B", a, b);
    47         MyThread pc = new MyThread("C", b, c);
    48         try {
    49             new Thread(pa).start();
    50             Thread.sleep(10);
    51             new Thread(pb).start();
    52             Thread.sleep(10);
    53             new Thread(pc).start();
    54         } catch (InterruptedException e) {
    55             e.printStackTrace();
    56         }
    57         
    58     }
    59 
    60 }

    这样就能真正的实现,第一遍运行顺序为ThreadA打印A,然后ThreadA等待->ThreadB打印B,然后B等待->ThreadC打印C,然后C等待并唤醒A;以此循环打印了。

    文章思路不是很清晰,主要还是学习别人写的东西,转化成自己能够理解的语言。努力学习中!

  • 相关阅读:
    python nltk nltk_data 离线安装,chatterbot
    ubuntu 16.04 64位 安装nvidia cuda
    发送imessage消息
    lua lor mongol socket.http
    pipenv
    headers参数格式化
    Linux删除空文件 空文件夹
    adb 操作安卓手机
    django 实现简单的检索功能
    1044: Access denied for user 'hehe'@'localhost' to database 'imooc'
  • 原文地址:https://www.cnblogs.com/qinglangyijiu/p/7699918.html
Copyright © 2011-2022 走看看