博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
三线程循环打印ABC流程解释
阅读量:5348 次
发布时间:2019-06-15

本文共 2625 字,大约阅读时间需要 8 分钟。

前言

昨天看了一个三线程循环打印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

你可能感兴趣的文章
php中eval函数的危害与正确禁用方法
查看>>
20172315 2017-2018-2 《程序设计与数据结构》第十一周学习总结
查看>>
MySQL添加、修改、撤销用户数据库操作权限的一些记录
查看>>
关于谷歌浏览器Chrome正在处理请求的问题解决
查看>>
Git核心技术:在Ubuntu下部署Gitolite服务端
查看>>
平面波展开法总结
查看>>
建造者模式
查看>>
ArraySort--冒泡排序、选择排序、插入排序工具类demo
查看>>
composer 安装laravel
查看>>
8-EasyNetQ之Send & Receive
查看>>
Android反编译教程
查看>>
List<string> 去重复 并且出现次数最多的排前面
查看>>
js日志管理-log4javascript学习小结
查看>>
Android之布局androidmanifest.xml 资源清单 概述
查看>>
How to Find Research Problems
查看>>
Linux用户管理
查看>>
数据库第1,2,3范式学习
查看>>
《Linux内核设计与实现》第四章学习笔记
查看>>
使用iperf测试网络性能
查看>>
图片的显示隐藏(两张图片,默认的时候显示第一张,点击的时候显示另一张)...
查看>>