线程 1 输出 a 5 次,线程 2 输出 b 5 次,线程 3 输出 c 5 次。现在要求输出 abcabcabcabcabc 怎么实现
第一种方法:使用wait与notify:
package com.DJL;
public class Code_交替输出_方法一 {
public static void main(String[] args) {
WaitNotify wf = new WaitNotify(1, 5);
new Thread(() -> {
wf.print("a", 1, 2);
}).start();
new Thread(() -> {
wf.print("b", 2, 3);
}).start();
new Thread(() -> {
wf.print("c", 3, 1);
}).start();
}
}
class WaitNotify {
int flag;
int loopNumber;
public WaitNotify(int flag, int loopNumber) {
this.flag = flag;
this.loopNumber = loopNumber;
}
public void print(String str, int waitFlag, int nextflag) {
for (int i = 0; i < loopNumber; i++) {
synchronized (this) {
while (flag != waitFlag) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(str);
flag = nextflag;
this.notifyAll();
}
}
}
}
第二种方法:使用ReentrantLock:
package com.DJL;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j(topic = "c.Code_交替输出_方法二")
public class Code_交替输出_方法二 {
public static void main(String[] args) {
waitNotify waitNotify = new waitNotify(5);
Condition a = waitNotify.newCondition();
Condition b = waitNotify.newCondition();
Condition c = waitNotify.newCondition();
new Thread(() -> {
waitNotify.print("a", a, b);
}).start();
new Thread(() -> {
waitNotify.print("b", b, c);
}).start();
new Thread(() -> {
waitNotify.print("c", c, a);
}).start();
log.debug("主线程获取lock锁.........");
waitNotify.lock();
try {
log.debug("start.......");
a.signal();
} finally {
waitNotify.unlock();
}
}
}
class waitNotify extends ReentrantLock {
int loopNumber;
public waitNotify(int loopNumber) {
this.loopNumber = loopNumber;
}
public void print(String str, Condition current, Condition next) {
for (int i = 0; i < loopNumber; i++) {
lock();
try {
current.await();
System.out.print(str);
next.signal();//唤醒下一个休息室中的线程
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
unlock();
}
}
}
}
第三种方法:使用park与unpark:
package com.DJL;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;
public class Code_交替输出_方法三 {
public static void main(String[] args) {
SyncPark sp = new SyncPark(5);
Thread t1 = new Thread(() -> {
sp.print("a");
});
Thread t2 = new Thread(() -> {
sp.print("b");
});
Thread t3 = new Thread(() -> {
sp.print("c");
});
sp.setThreads(t1, t2, t3);
sp.start();
}
}
class SyncPark {
private int loopNumber;
private Thread[] threads;
public SyncPark(int loopNumber) {
this.loopNumber = loopNumber;
}
public void setThreads(Thread... threads) {
this.threads = threads;
}
public void print(String str) {
for (int i = 0; i < loopNumber; i++) {
LockSupport.park();
System.out.print(str);
LockSupport.unpark(nextThread());
}
}
public Thread nextThread() {
Thread current = Thread.currentThread();
int index = 0;
for (int i = 0; i < threads.length; i++) {
if (current == threads[i]) {
index = i;
break;
}
}
if (index < threads.length - 1) {
return threads[index + 1];
} else {
return threads[0];
}
}
public void start() {
for (Thread thread : threads) {
thread.start();
}
LockSupport.unpark(threads[0]);
}
}