面试题 多线程并发 两个线程交替打印 三个线程交替打印
两个线程交替打印
public class Test2 { private static int count = 0; private final static Object lock = new Object(); static class TurningRunner implements Runnable { @Override public void run() { while (count <= 10) { // 获取锁 synchronized (lock) { // 拿到锁就打印 System.out.println(Thread.currentThread().getName() + ":" + count++); // 唤醒其他线程 lock.notifyAll(); try { // 如果任务还没有结束,则让出当前的锁并休眠 if (count <= 10) { lock.wait(); } } catch (InterruptedException e) { e.printStackTrace(); } } } } } public static void main(String[] args) throws InterruptedException { Thread a = new Thread(new TurningRunner(), "偶数"); Thread b = new Thread(new TurningRunner(), "奇数"); a.start(); b.start(); } }
三个线程交替打印
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class PrintNumber extends Thread {
/**
* 多个线程共享这一个sequence数据
*/
private static int sequence = 1;
private static final int SEQUENCE_END =75;
private int id;
private static ReentrantLock lock = new ReentrantLock();
private static Condition[] conditions = {lock.newCondition(),lock.newCondition(),lock.newCondition()};
private PrintNumber(int id) {
this.id = id;
this.setName("线程:" + (id + 1));
}
@Override
public void run() {
while (sequence < SEQUENCE_END) {
lock.lock();
try {
//对序号取模,如果不等于当前线程的id,则先唤醒其他线程,然后当前线程进入等待状态
while ((sequence/5) % conditions.length != id) {
conditions[(id + 1) % conditions.length].signal();
conditions[id].await();
}
for(int i = 0; i < 5; i++)
{
System.out.println(Thread.currentThread().getName() + " " + sequence++);
}
//唤醒当前线程的下一个线程
conditions[(id + 1) % conditions.length].signal();
//当前线程进入等待状态
conditions[id].await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//将释放锁的操作放到finally代码块中,保证锁一定会释放
lock.unlock();
}
}
//数字打印完毕,线程结束前唤醒其余的线程,让其他线程也可以结束
end();
}
private void end() {
lock.lock();
conditions[(id + 1) % conditions.length].signal();
conditions[(id + 2) % conditions.length].signal();
lock.unlock();
}
public static void main(String[] args) {
int threadCount = 3;
// ReentrantLock lock = new ReentrantLock();
// Condition[] conditions = new Condition[threadCount];
// for (int i = 0; i < threadCount; i++) {
// conditions[i] = lock.newCondition();
// }
PrintNumber[] printNumbers = new PrintNumber[threadCount];
for (int i = 0; i < threadCount; i++) {
printNumbers[i] = new PrintNumber(i);
}
for (PrintNumber printNumber : printNumbers) {
printNumber.start();
}
}
}