最近面试的时候会遇到这样的问题,竟然没有写出来,还是自己多练习吧 需求是这样的:
三个线程分别打印字符 a
、b
、c
,每个周期(即一次 abc
)打印完成后换行
如果是让连续a b c 分开换行 只需要更改print的逻辑即可,不用在区分abc了
Synchronized
java
package com.example.test;
public class Thread13 {
private static final Object lock = new Object();
private static int turn = 0; // 新增共享变量,记录当前该执行的线程编号
public static void main(String[] args) {
// 复用 print 方法创建线程
Thread thread1 = new Thread(() -> print('a', 0));
Thread thread2 = new Thread(() -> print('b', 1));
Thread thread3 = new Thread(() -> print('c', 2));
thread1.start();
thread2.start();
thread3.start();
}
// 合并后的打印方法
public static void print(char c, int n) {
for (int i = 0; i < 10; i++) {
synchronized (lock) {
// 使用 while 循环,确保线程被唤醒后再次检查条件
while (turn != n) {
try {
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
if (c == 'c') {
System.out.println(c);
} else {
System.out.print(c);
}
turn = (turn + 1) % 3; // 更新 turn 变量,让下一个线程执行
lock.notifyAll();
}
}
}
}
ReentrantLock 和 Condition
java
package com.example.test;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class thread14 {
private static final int TOTAL_ITERATIONS = 10;
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 char current = 'a';
public static void main(String[] args) {
Thread threadA = new Thread(() -> printChar('a', conditionA, conditionB, 'b'));
Thread threadB = new Thread(() -> printChar('b', conditionB, conditionC, 'c'));
Thread threadC = new Thread(() -> printChar('c', conditionC, conditionA, 'a'));
threadA.start();
threadB.start();
threadC.start();
// 等待所有线程完成
try {
threadA.join();
threadB.join();
threadC.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
System.out.println("\n所有线程打印完成!");
}
private static void printChar(char character, Condition currentCondition, Condition nextCondition, char nextCharacter) {
for (int i = 0; i < TOTAL_ITERATIONS; i++) {
lock.lock();
try {
while (current != character) {
currentCondition.await();
}
System.out.print(character);
// 判断是否是第三个线程打印后换行
if (character == 'c') {
System.out.println();
}
current = nextCharacter;
nextCondition.signal();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
} finally {
lock.unlock();
}
}
}
}
Semaphore
java
package com.example.test;
import java.util.concurrent.Semaphore;
public class thread15 {
private static final int TOTAL_ITERATIONS = 10;
private static Semaphore semaphoreA = new Semaphore(1);
private static Semaphore semaphoreB = new Semaphore(0);
private static Semaphore semaphoreC = new Semaphore(0);
public static void main(String[] args) {
Thread threadA = new Thread(() -> printChar('a', semaphoreA, semaphoreB));
Thread threadB = new Thread(() -> printChar('b', semaphoreB, semaphoreC));
Thread threadC = new Thread(() -> printChar('c', semaphoreC, semaphoreA));
threadA.start();
threadB.start();
threadC.start();
// 等待所有线程完成
try {
threadA.join();
threadB.join();
threadC.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
System.out.println("\n所有线程打印完成!");
}
private static void printChar(char character, Semaphore currentSemaphore, Semaphore nextSemaphore) {
for (int i = 0; i < TOTAL_ITERATIONS; i++) {
try {
currentSemaphore.acquire();
System.out.print(character);
// 判断是否是第三个线程打印后换行
if (character == 'c') {
System.out.println();
}
nextSemaphore.release();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
}
}
}