有两个字符数组
- number = {‘1’,‘2’,‘3’,‘4’,‘5’,‘6’,‘7’,‘8’,‘9’}
- letter = {‘A’,‘B’,‘C’,‘D’,‘E’,‘F’,‘G’,‘H’,‘I’}
要求启动2个线程,交替打印其中元素,输出结果为
- 1 A 2 B 3 C 4 D 5 E 6 F 7 G 8 H 9 I
本文给出类LockSupport,自旋锁,wait/notify,ReentrantLock实现该功能的方式。还有一些方法比如Semaphore(使用信号量实现限流,通过acquire和release方式每次只允许一个线程执行)、BlockingQueue(需要用两个BlockingQueue,通过两个BlockingQueue之间的信息交互和put、take方法达成功能)、管道流(PipedStream),这些方法也可以完成功能,请读者自行考虑实现。
LockSupport的方法
最简单的的一种方式,使用park和unpark的方式完成两个线程之间的通信
public static void main(String[] args) {
char[] number = {
'1','2','3','4','5','6','7','8','9'};
char[] letter = {
'A','B','C','D','E','F','G','H','I'};
t1 = new Thread(() ->{
for(char num : number){
System.out.print(num + " ");
LockSupport.unpark(t2); //唤醒t2线程
LockSupport.park(); //将本线程阻塞
}
});
t2 = new Thread(() ->{
for(char let : letter){
LockSupport.park(); //防止t2线程先执行从而先输出A
System.out.print(let + " ");
LockSupport.unpark(t1); //唤醒t1线程
}
});
t1.start();
t2.start();
}
模拟自旋锁的方式
使用一个原子类型的值当作自旋的标示,如果线程要执行时发现标示不对,则一直while自旋等待
static final AtomicInteger threadNo = new AtomicInteger(1);
public static void main(String[] args) {
char[] number = {
'1','2','3','4','5','6','7','8','9'};
char[] letter = {
'A','B','C','D','E','F','G'