###
/**
题目:现在两个线程,可以操作初始值为零的一个变量,
实现一个线程对该变量加1,一个线程对该变量-1,
实现交替,来10轮,变量初始值为0.
1. 高内聚低耦合前提下,线程操作资源类
2. 判断/干活/通知
3. 多线程中交互中 必须要,防止多线程的虚假唤醒(判断只能用while,不能用if)
知识小总结:多线程编程套路+while判断+新版写法
————————————————————————–
1.高内聚低耦合前提下,线程操作资源类
2.判断/干活/通知
3.多线程交互中,防止虚假唤醒(判断只能用while,不能用if)
4.标志位
一、利用synchronized锁
package com.xiao.test; /**
* @author zhangxiao
* @qq 490433117
* @create_date 2022/6/7 9:27
*/
import com.sun.media.jfxmediaimpl.HostUtils;
import org.junit.Test;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author zhangxiao
* @date 2022/6/7 9:27
*/
// 线程通信 一个线程加1 一个线程减1
public class ThreadWaitNotifyDemo {
public static void main(String[] args) {
AirCondtioner airCondtioner = new AirCondtioner();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
airCondtioner.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "加1线程A").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
airCondtioner.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "加1线程B").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
airCondtioner.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "减1线程C").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
airCondtioner.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "减1线程D").start();
}
}
class AirCondtioner {
private int num = 0;
// +1
public synchronized void increment() throws InterruptedException {
// 判断
while (num != 0) {
this.wait();
}
// 干活
num++;
System.out.println(Thread.currentThread().getName() + "\t" + num);
// 通知
this.notifyAll();
}
// +1
public synchronized void decrement() throws InterruptedException {
// 判断
while (num == 0) {
this.wait();
}
// 干活
num--;
System.out.println(Thread.currentThread().getName() + "\t" + num);
// 通知
this.notifyAll();
}
}
一、利用Lock锁
/**
* 资源类
*/
class AirCondtioner {
private int num = 0;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
// +1
public void increment() throws InterruptedException {
// 判断
try {
lock.lock();
while (num != 0) {
condition.await();
}
// 干活
num++;
System.out.println(Thread.currentThread().getName() + "\t" + num);
// 通知
condition.signalAll();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
lock.unlock();
}
}
// +1
public void decrement() throws InterruptedException {
// 判断
try {
lock.lock();
while (num == 0) {
condition.await();
}
// 干活
num--;
System.out.println(Thread.currentThread().getName() + "\t" + num);
// 通知
condition.signalAll();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
lock.unlock();
}
}
}
多线程之间按顺序调用,实现A->B->C
/**
* @author zhangxiao
* @qq 490433117
* @create_date 2022/6/8 9:57
*/
package com.xiao.test;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author zhangxiao
* @date 2022/6/8 9:57
*/
public class ShareThread {
public static void main(String[] args) {
ShareData shareData = new ShareData();
new Thread(()->{
for (int i = 0; i < 10; i++) {
shareData.print5();
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
shareData.print10();
}
},"B").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
shareData.print15();
}
},"C").start();
}
}
/**
* 多线程之间按顺序调用,实现A->B->C
* 三个线程启动,要求如下:
* AA打印5次,BB打印10次,CC打印15次
* 接着
* AA打印5次,BB打印10次,CC打印15次
* 来10轮
*/
class ShareData {
private int num = 1;
private Lock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private Condition condition3 = lock.newCondition();
public void print5() {
try {
lock.lock();
while (num != 1) {
condition1.await();
}
// 干活
for (int i = 0; i < 5; i++) {
System.out.println("print " + i);
}
// 通知
num = 2;
condition1.signal();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
lock.unlock();
}
}
public void print10() {
try {
lock.lock();
while (num != 2) {
condition1.await();
}
// 干活
for (int i = 0; i < 10; i++) {
System.out.println("print " + i);
}
// 通知
num = 3;
condition2.signal();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
lock.unlock();
}
}
public void print15() {
try {
lock.lock();
while (num != 3) {
condition3.await();
}
// 干活
for (int i = 0; i < 15; i++) {
System.out.println("print " + i);
}
// 通知
num = 1;
condition3.signal();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
lock.unlock();
}
}
}