目录
题目
使用三个线程 T1、T2、T3,如何让他们按顺序交替打印 10 次 A B C。
方案一:synchronized
public class SynchronizedLockPrinter {
static class Printer {
private final Object lock = new Object();
private static int count = 0;
public void print(int n, int target, char content) {
for (int i = 0; i < n; ) {
synchronized (lock) {
while (count % 3 != target) {
try {
lock.wait();
} catch (Exception e) {
System.out.println(e);
}
}
System.out.print(content);
count++;
i++;
lock.notifyAll();
}
}
}
public void print() {
new Thread(()-> {print(10, 0, 'A');}).start();
new Thread(()-> {print(10, 1, 'B');}).start();
new Thread(()-> {print(10, 2, 'C');}).start();
}
}
public static void main(String [] args) {
new Printer().print();
}
}
方法二:ReentrantLock
public class SignalLockPrinter {
static class Printer {
private final Lock lock = new ReentrantLock();
private static int count = 0;
public void print(int n, int target, char content) {
for (int i = 0; i < n; ) {
lock.lock();
try {
while (count % 3 == target) {
System.out.print(content);
count++;
i++;
}
} catch (Exception e) {
System.out.println(e);
} finally {
lock.unlock();
}
}
}
public void print() {
new Thread(()-> {print(10, 0, 'A');}).start();
new Thread(()-> {print(10, 1, 'B');}).start();
new Thread(()-> {print(10, 2, 'C');}).start();
}
}
public static void main(String [] args) {
new Printer().print();
}
}
方法三:ReentrantLock + Condition(非公平锁)
public class UnfairLockConditionPrinter {
static class ConditionPrinter {
private final Lock lock = new ReentrantLock(); // 非公平锁
private static int count = 0;
private final int threadNumber = 10;
private final Condition condition1 = lock.newCondition();
private final Condition condition2 = lock.newCondition();
private final Condition condition3 = lock.newCondition();
public void print(int target, String content, Condition current, Condition next) {
for (int i = 0; i < threadNumber; i++) {
lock.lock();
try {
// 执行临界区代码前判断:防止锁被不满足条件的线程抢占
while (count % 3 != target) {
current.await(); // 条件等待并释放锁
}
System.out.print(content);
count++;
next.signal(); // 唤醒一个等待该条件的线程
} catch (Exception e) {
System.out.println(e);
} finally {
lock.unlock();
}
}
}
public void print() {
new Thread(() -> {print(0, "A", condition1, condition2);}).start();
new Thread(() -> {print(1, "B", condition2, condition3);}).start();
new Thread(() -> {print(2, "C", condition3, condition1);}).start();
}
}
public static void main(String[] args) {
new ConditionPrinter().print();
}
}
注意,unlock()
并不会阻塞当前线程,所以,当 A 线程在释放锁后,线程状态并没有改变,所以 A 线程还会去尝试获取一次锁,如果获取锁失败,就会进入阻塞状态;如果获取成功,就会进入条件等待状态。
优化:改成公平锁,可以减少锁的竞争程度。
方法四:ReentrantLock + Condition(公平锁)
public class FairLockConditionPrinter {
static class ConditionPrinterEnhance {
private final Lock lock = new ReentrantLock(true);
private final Condition condition = lock.newCondition();
private static int count = 0;
private final int threadNumber = 10;
public void print(int target, char content) {
lock.lock();
try {
for (int i = 0; i < threadNumber; i++) {
while (count % 3 != target) {
condition.await();
}
System.out.println(Thread.currentThread().getName() + ": " + content + " " + count);
count++;
condition.signal();
}
} catch (Exception e) {
System.out.println(e);
} finally {
lock.unlock();
}
}
public void print() {
char content = 'A';
for (int i = 0; i < 3; i++) {
final int k = i;
new Thread(() -> print( k, (char) (content + k))).start();
}
}
}
public static void main(String[] args) {
new ConditionPrinterEnhance().print();
}
}
方法五:Semaphore
public class SemaphorePrinter {
static class Printer {
private final int n = 10;
private final Semaphore s1 = new Semaphore(1);
private final Semaphore s2 = new Semaphore(0);
private final Semaphore s3 = new Semaphore(0);
private void print(char content, Semaphore current, Semaphore next) {
for (int i = 0; i < n; i++) {
try {
current.acquire();
System.out.print(content);
next.release();
} catch (Exception e) {
System.out.println(e);
}
}
}
public void print() {
new Thread(() -> {print('A', s1, s2);}).start();
new Thread(() -> {print('B', s2, s3);}).start();
new Thread(() -> {print('C', s3, s1);}).start();
}
}
public static void main(String [] args) {
new Printer().print();
}
}
标签:Java,int,lock,打印,private,print,new,多线程,public
From: https://www.cnblogs.com/larry1024/p/17986059