按照abcabcabc方式打印十次
先从两个线程打印ababab入手,可以通过synchronize+wait/notify的方式实现
private static void printWith2Threads() throws InterruptedException {
Object lock = new Object();
//两个线程打印ab 只需要一把锁即可 wait方法会释放当前锁并进入阻塞等待状态
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
synchronized (lock) {
System.out.print("a");
// 唤醒另一个线程 并使其进入等待状态 准备争抢锁
lock.notify();
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "thread1");
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
synchronized (lock) {
System.out.print("b");
lock.notify();
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "thread2");
thread1.start();
Thread.sleep(100);
thread2.start();
}
三个线程打印,一把锁显然是不够的,无法保证顺序打印,结合wait/notify的特性,代码如下
先创建三把锁,分别每个线程需要操作两把锁,线程1先获取lock1,打印a,随后唤醒等待lock2的线程,并释放lock2,调用wait方法释放lock1 并进入lock1的等待室,等待其他线程唤醒。线程2被线程1唤醒,占有lock2,打印b,占有lock3,并通知线程3,随后释放lock3,进入lock2的等待室。线程3同理。
每一个线程都会先打印,然后唤醒下一个打印的线程并释放锁,随后自己进入等待室。
private static void printWith3Threads() throws InterruptedException {
Object lock1 = new Object();
Object lock2 = new Object();
Object lock3 = new Object();
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
synchronized (lock1) {
System.out.print("a");
synchronized (lock2){
lock2.notify();
}
try {
// 进入lock1的等待室 并释放锁
lock1.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "thread1");
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
synchronized (lock2) {
System.out.print("b");
synchronized (lock3){
lock3.notify();
}
try {
lock2.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "thread2");
Thread thread3 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
synchronized (lock3) {
System.out.print("c");
synchronized (lock1){
lock1.notify();
}
try {
lock3.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "thread3");
thread1.start();
Thread.sleep(100);
thread2.start();
Thread.sleep(100);
thread3.start();
}