交替打印100个字母/交替打印循环100次(一共300个)
-
方案一.使用ReentrantLock + Condition
class ABCPrinter {//使用ReentrantLock + condition //这里指的是三个线程总共打印100个
private static final int PRINT_COUNT = 100;
private static volatile int count = 0;//静态保证类的所有对象都共享一份 volatile保证可见性,禁止指令重排序
private static final Lock lock = new ReentrantLock();
private static final Condition conditionA = lock.newCondition();
private static final Condition conditionB = lock.newCondition();
private static final Condition conditionC = lock.newCondition();
public static void main(String[] args) {
new Thread(() -> println("a", conditionA, conditionB)).start();
new Thread(() -> println("b", conditionB, conditionC)).start();
new Thread(() -> println("c", conditionC, conditionA)).start();
}
private static void println(String str, Condition current, Condition next) {
try {
lock.lock();
while (count < PRINT_COUNT) {
while (count % 3 != getThreadIndex(str)) {//套while循环 防止虚假唤醒
current.await();
}
if(count<PRINT_COUNT){//双重判断 防止最后阻塞的线程唤醒后 打印数字超过范围
System.out.println(Thread.currentThread().getName() + " : " + count +" : " + str);
}
count++;
next.signal();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
private static int getThreadIndex(String str) {
switch (str) {
case "a":
return 0;
case "b":
return 1;
case "c":
return 2;
default:
throw new IllegalArgumentException("Invalid thread name");
}
}
}
效果展示
![](https://i-blog.csdnimg.cn/blog_migrate/150f5c6c96e7c5bcb6e29eea89bca77d.png)
每个线程分别打印100个,交替打印
class ABCPrinter2 {//每个线程分别打印100个
private static final int PRINT_COUNT = 100;
private static final Lock lock = new ReentrantLock();
private static final Condition conditionA = lock.newCondition();
private static final Condition conditionB = lock.newCondition();
private static final Condition conditionC = lock.newCondition();
private static volatile int count = 0;
public static void main(String[] args) {
Runnable printA = () -> print("a", conditionA, conditionB);
Runnable printB = () -> print("b", conditionB, conditionC);
Runnable printC = () -> print("c", conditionC, conditionA);
new Thread(printA).start();
new Thread(printB).start();
new Thread(printC).start();
}
private static void print(String str, Condition current, Condition next) {
lock.lock();
try {
for (int i = 0; i < PRINT_COUNT; i++) {
while (count % 3 != getThreadIndex(str)) {
current.await();
}
System.out.println(Thread.currentThread().getName() + " : " + i + " : " + str);
count++;
next.signal();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
private static int getThreadIndex(String str) {
switch (str) {
case "a":
return 0;
case "b":
return 1;
case "c":
return 2;
default:
throw new IllegalArgumentException("Invalid thread name");
}
}
}
效果展示
![](https://i-blog.csdnimg.cn/blog_migrate/e07a4c83840a16bc34cd2ed0a4b4518e.png)
class PrintABCUsingSemaphore { //使用semaphore
private static Semaphore semaphoreA = new Semaphore(1);//通过permits控制 1表示允许一个线程共享
private static Semaphore semaphoreB = new Semaphore(0);//为0 acquire()时直接阻塞
private static Semaphore semaphoreC = new Semaphore(0);
public static void main(String[] args) {
Runnable printA = new PrintTask('A', semaphoreA, semaphoreB);
Runnable printB = new PrintTask('B', semaphoreB, semaphoreC);
Runnable printC = new PrintTask('C', semaphoreC, semaphoreA);
Thread threadA = new Thread(printA);
Thread threadB = new Thread(printB);
Thread threadC = new Thread(printC);
threadA.start();
threadB.start();
threadC.start();
}
static class PrintTask implements Runnable {
private static final int TOTAL_COUNT = 100;
private static volatile int count = 0;
private char letter;
private Semaphore currentSemaphore;
private Semaphore nextSemaphore;
public PrintTask(char letter, Semaphore currentSemaphore, Semaphore nextSemaphore) {
this.letter = letter;
this.currentSemaphore = currentSemaphore;
this.nextSemaphore = nextSemaphore;
}
@Override
public void run() {
try {
while (count < TOTAL_COUNT) {
currentSemaphore.acquire();//就算BC线程率先执行也会因为没有permits而阻塞在这里
if(count<TOTAL_COUNT){
System.out.println(Thread.currentThread().getName() + " : " + count + " : " + letter);
count++;
}
nextSemaphore.release();//让下一个允许执行的线程数量增加0->1
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
效果展示
![](https://i-blog.csdnimg.cn/blog_migrate/86fdafa75785fe524ec68acb276777c3.png)
每个线程分别打印100个,交替打印
class PrintABCUsingSemaphore2 {
private static Semaphore semaphoreA = new Semaphore(1);
private static Semaphore semaphoreB = new Semaphore(0);
private static Semaphore semaphoreC = new Semaphore(0);
private static final int TOTAL_COUNT = 100;
public static void main(String[] args) {
Thread threadA = new Thread(() -> printLetter('A', semaphoreA, semaphoreB));
Thread threadB = new Thread(() -> printLetter('B', semaphoreB, semaphoreC));
Thread threadC = new Thread(() -> printLetter('C', semaphoreC, semaphoreA));
threadA.start();
threadB.start();
threadC.start();
}
public static void printLetter(char letter, Semaphore currentSemaphore, Semaphore nextSemaphore) {
try {
int count = 0;//每个对象都有一份自己的
while (count < TOTAL_COUNT) {//for循环也行
currentSemaphore.acquire();
System.out.println(Thread.currentThread().getName() + " : " + count + " : " + letter);
count++;
nextSemaphore.release();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
效果展示
![](https://i-blog.csdnimg.cn/blog_migrate/2d0c599b8534452eb902ea8c2ab0ef7f.png)