synchronized版:
package day3;
/**
* @author jitwxs
* @date 2021年05月11日 20:31
*/
/*
* 线程之间通信问题:生产者消费者问题 等待唤醒,通知唤醒
* 线程交替执行 A B 操作同一个变量 num = 0
* A num+1
* B num-1
*/
public class A {
public static void main(String[] args) {
Data data = new Data();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.increment();
} catch (Exception e) {
e.printStackTrace();
}
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.decrement();
} catch (Exception e) {
e.printStackTrace();
}
}
},"B").start();
}
}
//判断等待,业务,通知
class Data{
private int num = 0;
//+1
public synchronized void increment() throws Exception{
if(num!=0){
//等待
this.wait();
}
num++;
System.out.println(Thread.currentThread().getName()+"==>"+num);
this.notifyAll();
}
//-1
public synchronized void decrement() throws Exception{
if(num==0){
//等待
this.wait();
}
num--;
System.out.println(Thread.currentThread().getName()+"==>"+num);
this.notifyAll();
}
}
问题存在:如果存在A,B,C,D四个线程!虚假唤醒
`改成while可以解决`:
package day3;
/**
* @author jitwxs
* @date 2021年05月11日 20:31
*/
/*
* 线程之间通信问题:生产者消费者问题 等待唤醒,通知唤醒
* 线程交替执行 A B 操作同一个变量 num = 0
* A num+1
* B num-1
*/
public class A {
public static void main(String[] args) {
Data data = new Data();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.increment();
} catch (Exception e) {
e.printStackTrace();
}
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.decrement();
} catch (Exception e) {
e.printStackTrace();
}
}
},"B").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.increment();
} catch (Exception e) {
e.printStackTrace();
}
}
},"C").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.decrement();
} catch (Exception e) {
e.printStackTrace();
}
}
},"D").start();
}
}
//判断等待,业务,通知
class Data{
private int num = 0;
//+1
public synchronized void increment() throws Exception{
while(num!=0){
//等待
this.wait();
}
num++;
System.out.println(Thread.currentThread().getName()+"==>"+num);
this.notifyAll();
}
//-1
public synchronized void decrement() throws Exception{
while(num==0){
//等待
this.wait();
}
num--;
System.out.println(Thread.currentThread().getName()+"==>"+num);
this.notifyAll();
}
}
JUC版
:
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
condition.await(); 等待
condition.signalAll(); 唤醒
package day3;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author jitwxs
* @date 2021年05月11日 20:31
*/
/*
* 线程之间通信问题:生产者消费者问题 等待唤醒,通知唤醒
* 线程交替执行 A B 操作同一个变量 num = 0
* A num+1
* B num-1
*/
public class B {
public static void main(String[] args) {
Data2 data = new Data2();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.increment();
} catch (Exception e) {
e.printStackTrace();
}
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.decrement();
} catch (Exception e) {
e.printStackTrace();
}
}
},"B").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.increment();
} catch (Exception e) {
e.printStackTrace();
}
}
},"C").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
data.decrement();
} catch (Exception e) {
e.printStackTrace();
}
}
},"D").start();
}
}
//判断等待,业务,通知
class Data2{
private int num = 0;
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
//+1
public void increment() throws Exception{
lock.lock();
try {
while(num!=0){
//等待
condition.await();
}
num++;
System.out.println(Thread.currentThread().getName()+"==>"+num);
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
//-1
public void decrement() throws Exception{
lock.lock();
try {
while(num==0){
//等待
condition.await();
}
num--;
System.out.println(Thread.currentThread().getName()+"==>"+num);
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
精准唤醒
package day3;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author jitwxs
* @date 2021年05月12日 19:44
*/
/*
* A执行完调用B,B执行完调用C
*/
public class C {
public static void main(String[] args) {
Data3 data3 = new Data3();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data3.printA();
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data3.printB();
}
},"B").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data3.printC();
}
},"C").start();
}
}
class Data3{ //资源类
private Lock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private Condition condition3 = lock.newCondition();
private int num = 1; //1A,2B,3C
public void printA(){
lock.lock();
try {//业务,判断,执行,通知
while (num!=1){
//等待
condition1.await();
}
System.out.println(Thread.currentThread().getName()+"====>AAAAA");
//唤醒指定的人
num = 2;
condition2.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void printB(){
lock.lock();
try {//业务,判断,执行,通知
while(num!=2){
condition2.await();
}
System.out.println(Thread.currentThread().getName()+"=====>BBBBB");
num = 3;
condition3.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void printC(){
lock.lock();
try {//业务,判断,执行,通知
while (num!=3){
condition3.await();
}
System.out.println(Thread.currentThread().getName()+"=====>CCCCCC");
num = 1;
condition1.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}