线程间通信的模型有两种:共享内存和消息传递
- 以下方式都是基本这两种模
型来实现的。我们来基本一道面试常见的题目来分析
场景—-两个线程,一个线程对当前数值加 1,另一个线程对当前数值减 1,要求
用线程间通信
synchronized方案
public class TestVolatile {
/**
* 交替加减
* @param args
*/
public static void main(String[] args){
DemoClass demoClass = new DemoClass();
new Thread(() ->{
for (int i = 0; i < 5; i++) {
demoClass.increment();
}
}, "线程 A").start();
new Thread(() ->{
for (int i = 0; i < 5; i++) {
demoClass.decrement();
}
}, "线程 B").start();
}
}
package com.atguigu.test;
class DemoClass{
//加减对象
private int number = 0;
/**
* 加 1
*/
public synchronized void increment() {
try {
while (number != 0){
this.wait();
}
number++;
System.out.println("--------" + Thread.currentThread().getName() + "加一成
功----------,值为:" + number);
notifyAll();
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 减一
*/
public synchronized void decrement(){
try {
while (number == 0){
this.wait();
}
number--;
System.out.println("--------" + Thread.currentThread().getName() + "减一成
功----------,值为:" + number);
notifyAll();
}catch (Exception e){
e.printStackTrace();
}
}
}
Lock方案
public class ThreadDemo1 {
private ReentrantLock reentrantLock = new ReentrantLock();
private Condition condition = reentrantLock.newCondition();
private int number = 0;
private void incr() {
reentrantLock.lock();
try {
while (number != 0) {
condition.await();
}
number++;
System.err.println("number::" + number);
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
reentrantLock.unlock();
}
}
private void decr() {
reentrantLock.lock();
try {
while (number != 1) {
condition.await();
}
number--;
System.err.println("number::" + number);
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
reentrantLock.unlock();
}
}
public static void main(String[] args) {
ThreadDemo1 demo1 = new ThreadDemo1();
new Thread(()->{
for (int i = 0; i < 5; i++) {
demo1.incr();
}
},"AA").start();
new Thread(()->{
for (int i = 0; i < 5; i++) {
demo1.incr();
}
},"BB").start();
new Thread(()->{
for (int i = 0; i < 5; i++) {
demo1.decr();
}
},"CC").start();
new Thread(()->{
for (int i = 0; i < 5; i++) {
demo1.decr();
}
},"DD").start();
}
}