如果一个线程从头到尾执行完也不和别的线程打交道的话,那就不会有各种安全性问题了。但是协作越来越成为社会发展的大势,一个大任务拆成若干个小任务之后,各个小任务之间可能也需要相互协作最终才能执行完整个大任务。所以各个线程在执行过程中可以相互通信,所谓通信就是指相互交换一些数据或者发送一些控制指令,比如一个线程给另一个暂停执行的线程发送一个恢复执行的指令,下边详细看都有哪些通信方式。

volatile和synchronized

可变共享变量是天然的通信媒介,也就是说一个线程如果想和另一个线程通信的话,可以修改某个在多线程间共享的变量,另一个线程通过读取这个共享变量来获取通信的内容。

由于原子性操作、内存可见性和指令重排序的存在,java提供了volatilesynchronized的同步手段来保证通信内容的正确性,假如没有这些同步手段,一个线程的写入不能被另一个线程立即观测到,那这种通信就是不靠谱的~

wait/notify机制

故事背景

也不知道是那个遭天杀的给我们学校厕所的坑里塞了个塑料瓶,导致楼道里如黄河泛滥一般,臭味熏天。更加悲催的是整个楼只有这么一个厕所,比这个更悲催的是这个厕所里只有一个坑!!!!!好吧,让我们用java来描述一下这个厕所:

public class Washroom {

    private volatile boolean isAvailable = false;    //表示厕所是否是可用的状态

    private Object lock = new Object(); //厕所门的锁

    public boolean isAvailable() {
return isAvailable;
} public void setAvailable(boolean available) {
this.isAvailable = available;
} public Object getLock() {
return lock;
}
}

isAvailable字段代表厕所是否可用,由于厕所损坏,默认是false的,lock字段代表这个厕所门的锁。需要注意的是isAvailable字段被volatile修饰,也就是说有一个线程修改了它的值,它可以立即对别的线程可见~

由于厕所资源宝贵,英明的学校领导立即拟定了一个修复任务:

public class RepairTask implements Runnable {

    private Washroom washroom;

    public RepairTask(Washroom washroom) {
this.washroom = washroom;
} @Override
public void run() { synchronized (washroom.getLock()) {
System.out.println("维修工 获取了厕所的锁");
System.out.println("厕所维修中,维修厕所是一件辛苦活,需要很长时间。。。"); try {
Thread.sleep(5000L); //用线程sleep表示维修的过程
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
washroom.setAvailable(true); //维修结束把厕所置为可用状态
System.out.println("维修工把厕所修好了,准备释放锁了");
}
}
}

这个维修计划的内容就是当维修工进入厕所之后,先把门锁上,然后开始维修,维修结束之后把WashroomisAvailable字段设置为true,以表示厕所可用。

与此同时,一群急得像热锅上的蚂蚁的家伙在厕所门前打转转,他们想做神马不用我明说了吧

最新文章

  1. js创建命名空间
  2. 《Effective Java》—— 对于所有对象都通用的方法
  3. 【python】入门学习(九)
  4. UIView 的autoresizingMask属性
  5. oracle给字段添加描述
  6. 在C,C++,JAVA中int,char,各占几个字节
  7. js函数延迟执行
  8. [原]RobotFrameWork(四)变量运算与Evaluate
  9. 计蒜客NOIP模拟赛4 D1T1 小X的质数
  10. UTL_HTTP Call a Web Service and Pass Parameters as Part of the URL
  11. 保证你能看懂的KMP字符串匹配算法
  12. 2 - Binary Search & LogN Algorithm - Apr 18
  13. android:动态申请权限(一)
  14. springboot + @KafkaListener 手动提交及消费能力优化
  15. 手动实现staticmethod和classmethod装饰器
  16. Python3实现Win10桌面背景自动切换
  17. 一本通1648【例 1】「NOIP2011」计算系数
  18. Spring Boot实践——用外部配置填充Bean属性的几种方法
  19. 分布式理论系列(三)ZAB 协议
  20. 小程序采坑之setData

热门文章

  1. node-amqp 使用fanout发布订阅rabbitmq消息
  2. Java语法基础(2)
  3. ae(ArcEngine) java swing开发入门系列(2):ae的类型转换和Proxy类说明
  4. acdream 小晴天老师系列——我有一个数列! (ST算法)
  5. BZOJ 3232: 圈地游戏 分数规划+判负环
  6. RYU的GUI安装
  7. python基础教程总结6——类
  8. ceisum_加载倾斜摄影模型
  9. Unity中的各种寻找GameObject方法归纳
  10. mybatis(一):思维导图