juc是java.util.current的简写,意思是并发编程。
锁是什么?如何判断锁的是谁?
生产者和消费者问题
synchronized版本
package com.demo.juc.pc;/*** 线程之间的通信问题,生产者和消费者问题!* 线程交替执行** a b 两个线程操作同一个变量 num* a num++* b num--** 这两条线程是互相隔离的,它们彼此不知道对方是++还是--* 需要一种机制使它们之间产生通信,* 比如a++后告诉b该--了,b--后再告诉a该++了** 解决:* 等待唤醒,通知唤醒**/
public class A {public static void main(String[] args) {Data data = new Data();new Thread(()->{for (int i = 0; i < 5; i++) {data.increment();}},"a").start();new Thread(()->{for (int i = 0; i < 5; i++) {data.decrement();}},"b").start();// a-->1//b-->0//a-->1//b-->0//a-->1//b-->0//a-->1//b-->0//a-->1//b-->0}}class Data{ // 数字,资源类private int number = 0;// ++public synchronized void increment(){if (number!=0){// 等待try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}number++;// 通知其他线程,++完毕,开始--System.out.println(Thread.currentThread().getName()+"-->"+number);this.notifyAll();}// --public synchronized void decrement(){if (number==0){// 等待try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}number--;System.out.println(Thread.currentThread().getName()+"-->"+number);this.notifyAll();}}
虚假唤醒
多线程环境下,有多个线程执行了wait()方法,需要其他线程执行notify()或者notifyAll()方法去唤醒它们,假如多个线程都被唤醒了,但是只有其中一部分是有用的唤醒操作,其余的唤醒都是无用功;对于不应该被唤醒的线程而言,便是虚假唤醒。
以上代码是两个线程,但是如果四个线程的话,线程就不安全了。
解决虚假唤醒的问题,只需将上面的if判断改为while即可。
为什么 if会出现虚假唤醒?
- 因为if只会执行一次,执行完会接着向下执行if(){}后边的逻辑;
- 而while不会,直到条件满足才会向下执行while(){}后边的逻辑。
如何避免虚假唤醒
使用while循环去循环判断一个条件,而不是使用if只判断一次条件;即wait()要在while循环中。
部分内容转载自:
https://blog.csdn.net/Saintmm/article/details/121092830
https://www.bilibili.com/video/BV1B7411L7tE/?p=8&spm_id_from=pageDriver&vd_source=64c73c596c59837e620fed47fa27ada7
无论你在背后喊刘怡婷或房思琪,我都会回头的。
房思琪的初恋乐园
林奕含