并发编程实战之三个线程同时运行交替打印 A B C
Synchronized 和 wait, notifyAll 的实现方式
java
package com.mengweijin.learning.basic.lock;
/**
* 三个线程同时运行交替打印 A B C,每个线程执行 3 次,总共打印 9 行
* ThreadA->ThreadB->ThreadC循环执行三个线程
* 锁释放之后所有线程疯抢争夺资源
*
* @author mengweijin
*/
public class AbcSynchronized {
public static void main(String[] args) {
Printer printer = new Printer();
new Thread(() -> printer.print("A", 1, 2), "t1").start();
new Thread(() -> printer.print("B", 2, 3), "t2").start();
new Thread(() -> printer.print("C", 3, 1), "t3").start();
}
static class Printer {
int flag = 1;
public void print(String context, int waitFlag, int nextFlag) {
try {
for (int i = 0; i < 3; i++) {
synchronized (this) {
while(flag != waitFlag) {
this.wait();
}
System.out.println(Thread.currentThread().getName() + ":" + context);
flag = nextFlag;
this.notifyAll();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
ReentrantLock 和 Condition 的实现方式
java
package com.mengweijin.learning.basic.lock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* 三个线程同时运行交替打印 A B C,每个线程执行 3 次,总共打印 9 行
* ThreadA->ThreadB->ThreadC循环执行三个线程
* 锁释放之后所有线程疯抢争夺资源
*
* @author mengweijin
*/
public class AbcReentrantLock {
public static void main(String[] args) {
Printer printer = new Printer();
new Thread(() -> printer.print("A", 1, 2), "t1").start();
new Thread(() -> printer.print("B", 2, 3), "t2").start();
new Thread(() -> printer.print("C", 3, 1), "t3").start();
}
static class Printer {
static final ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
int flag = 1;
public void print(String context, int waitFlag, int nextFlag) {
for (int i = 0; i < 5; i++) {
lock.lock();
try {
while (flag != waitFlag) {
condition.await();
}
System.out.println(Thread.currentThread().getName() + ":" + context);
flag = nextFlag;
condition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
}
ReentrantLock 和 Condition 的实现方式 —— 优化一
java
package com.mengweijin.learning.basic.lock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* 三个线程同时运行交替打印 A B C,每个线程执行 3 次,总共打印 9 行
* ThreadA->ThreadB->ThreadC循环执行三个线程
* 锁释放之后所有线程按照条件唤醒,不用再疯抢争夺资源
*
* @author mengweijin
*/
public class AbcReentrantLockBest {
private static final int TIMES = 3;
public static void main(String[] args) {
Printer printer = new Printer();
new Thread(() -> {
for (int i = 0; i < TIMES; i++) {
printer.printA("A", 1, 2);
}
}, "t1").start();
new Thread(() -> {
for (int i = 0; i < TIMES; i++) {
printer.printB("B", 2, 3);
}
}, "t2").start();
new Thread(() -> {
for (int i = 0; i < TIMES; i++) {
printer.printC("C", 3, 1);
}
}, "t3").start();
}
static class Printer {
static final ReentrantLock lock = new ReentrantLock();
Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
Condition conditionC = lock.newCondition();
int flag = 1;
public void printA(String context, int waitFlag, int nextFlag) {
lock.lock();
try {
while (flag != waitFlag) {
conditionA.await();
}
System.out.println(Thread.currentThread().getName() + ":" + context);
flag = nextFlag;
conditionB.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void printB(String context, int waitFlag, int nextFlag) {
lock.lock();
try {
while (flag != waitFlag) {
conditionB.await();
}
System.out.println(Thread.currentThread().getName() + ":" + context);
flag = nextFlag;
conditionC.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void printC(String context, int waitFlag, int nextFlag) {
lock.lock();
try {
while (flag != waitFlag) {
conditionC.await();
}
System.out.println(Thread.currentThread().getName() + ":" + context);
flag = nextFlag;
conditionA.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
ReentrantLock 和 Condition 的实现方式 —— 优化二
java
package com.mengweijin.learning.basic.lock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* 三个线程同时运行交替打印 A B C,每个线程执行 3 次,总共打印 9 行
* ThreadA->ThreadB->ThreadC循环执行三个线程
* 锁释放之后所有线程按照条件唤醒,不用再疯抢争夺资源
*
* @author mengweijin
*/
public class AbcReentrantLockBestOptimize {
private static final int TIMES = 3;
public static void main(String[] args) {
Printer printer = new Printer();
new Thread(() -> printer.print("A", 1, 2, printer.conditionA, printer.conditionB), "t1").start();
new Thread(() -> printer.print("B", 2, 3, printer.conditionB, printer.conditionC), "t2").start();
new Thread(() -> printer.print("C", 3, 1, printer.conditionC, printer.conditionA), "t3").start();
}
static class Printer {
static final ReentrantLock lock = new ReentrantLock();
Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
Condition conditionC = lock.newCondition();
int flag = 1;
public void print(String context, int waitFlag, int nextFlag, Condition waitCondition, Condition signalCondition) {
for (int i = 0; i < TIMES; i++) {
lock.lock();
try {
while (flag != waitFlag) {
waitCondition.await();
}
System.out.println(Thread.currentThread().getName() + ":" + context);
flag = nextFlag;
signalCondition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
}