三线程循环打印ABC流程解释

前言

昨天看了一个三线程循环打印ABC的经典例子,看了很多博客感觉都没有讲清楚具体的执行流程,而且对于方法的解释也是没有完全没有解释好,和朋友讨论解决了这个问题,写下这篇博客,来解释三线程同步打印的问题,所以不能完全相信博客的解释,最好还是看官方的注释和源码。

先上实例以及输出

public class HjsjyThread implements Runnable {   
  
    private String name;   
    private Object prev;   
    private Object self;   
  
    private  HjsjyThread(String name, Object prev, Object self) {   
        this.name = name;   
        this.prev = prev;   
        this.self = self;   
    }   
  
    @Override  
    public void run() {   
        int count = 10;   
        while (count > 0) {   
            synchronized (prev) {   
                synchronized (self) {   
                    System.out.print(name);   
                    count--;  
                    try{
                    Thread.sleep(1);
                    }
                    catch (InterruptedException e){
                     e.printStackTrace();
                    }
                    
                    self.notify();   
                }   
                try {   
                    prev.wait();   
                } catch (InterruptedException e) {   
                    e.printStackTrace();   
                }   
            }   
  
        }   
    }   
  
    public static void main(String[] args) throws Exception {   
        Object a = new Object();   
        Object b = new Object();   
        Object c = new Object();   
        HjsjyThread pa = new  HjsjyThread("A", c, a);   
        HjsjyThread pb = new  HjsjyThread("B", a, b);   
        HjsjyThread pc = new  HjsjyThread("C", b, c);   
           
           
        new Thread(pa).start();
        Thread.sleep(100);
        new Thread(pb).start();
        Thread.sleep(100);
        new Thread(pc).start();
        Thread.sleep(100);
    }   
}
//输出:ABCABCABCABCABCABCABCABCABCABC

主要问题

  • notify()的解释 (重要
    我先搬出源码上的注释
Wakes up a  single thread that is waiting on this object’s monitor. if any thread are waiting on this object ,one of them is chosen to be awakened.

这段英文还是挺简单的 唤醒任意一个 正在等待当前对象的waiting线程,重点就是在这个正在等待当前对象这句话,这是第一个作用,另外notify()并不是立刻释放对象锁,而是要等出临界区 也就是在这个例子里面的内synchronized。出去之后线程才会释放对象锁

  • wait()
    wait也是有两个作用,一个是使当前线程进入等待状态,二是使当前对象锁立刻释放。

执行流程

主线程开启,执行A线程,获得 c, a锁, 输出A count为9,这时self.notify()也就是a.notify(),当前没有正在等待a对象锁的wait 线程所以只有释放锁的作用,接着执行 c.wait() ,释放c锁,并且让当前线程也就是A线程等待,接着执行B线程 B线程等待A锁的释放(因为notify()不是立刻释放锁的,具体可以看上面notify 方法的解释),得到a ,b锁之后输出B count=9,执行b.notify(),也没有当前wait 等待b锁的wait线程 所以也有释放锁的功能,接着a.wait,b线程d等待 立刻释放锁a,接着执行C线程,需要等待B线程释放b锁,得到b c锁执行,输出C然后count=9,然后c.notify() 当前有正在等待c的wait线程 也就是A线程,C线程执行b.wait 让C线程d等待并且立刻释放b锁,A需要等待C线程释放c锁 如此循环打印。

原文地址:https://www.cnblogs.com/narojay/p/10812585.html