经典面试题:俩线程交替打印数字字母 例如:1A2B3C4D
骚操作:利用阻塞队列实现
ArrayBlockingQueue queue1 = new ArrayBlockingQueue(1);
// 有界队列外面只有一个
ArrayBlockingQueue queue2 = new ArrayBlockingQueue(1);
char[] a = {'1', '2', '3'};
char[] b = {'a', 'b', 'c'};
new Thread(() -> {for (char c : a) {
try {
// 如果容器为空 put 会期待
queue1.put(c);
System.out.println(queue2.take());
Thread.sleep(1000);
} catch (InterruptedException e) {e.printStackTrace();
}
}
}, "t1").start();
new Thread(() -> {for (char f : b) {
try {
//take 容器为空 也期待
System.out.println(queue1.take());
// 指定 q2 put
queue2.put(f);
Thread.sleep(1000);
} catch (InterruptedException e) {e.printStackTrace();
}
}
}, "t2").start();
// 每次队列只有 1 个 t1 线程打印 t2 t2 打印 t1
// 输入 就是 1A2B3C
2. 利用 synchronized 同步锁 wait() notify(notifyAll)
/** 定义对象锁 */
final Object obj = new Object();
char[] charsA = new char[] {'A', 'B', 'C', 'D'};
char[] charsB = new char[] {'1', '2', '3', '4'};
/** 线程 1 */
new Thread(() -> {
/** 对象锁 */
synchronized (obj) {for (char c : charsB) {System.out.println(c);
try {
/** 叫醒 */
obj.notify();
/** 期待 让出锁 */
obj.wait();} catch (InterruptedException e) {e.printStackTrace();
}
}
// 让线程终止
obj.notify();}
},
"t1")
.start();
new Thread(() -> {synchronized (obj) {for (char b : charsA) {System.out.println(b);
try {obj.notify();
obj.wait();} catch (InterruptedException e) {e.printStackTrace();
}
}
obj.notify();}
},
"t2")
.start();}
-----------------------------------------------------------
char[] a = {'1', '2', '3', '4', '5'};
char[] b = {'A', 'B', 'C', 'D', 'E'};
// 打印 1A2B。。。//wait notify()
final Object lock = new Object();
new Thread(() -> {synchronized (lock) {for (char zimu : b) {
//wait
try {lock.wait();
System.out.println(zimu);
lock.notify();} catch (InterruptedException e) {e.printStackTrace();
}
}
}
}, "t1").start();
new Thread(() -> {synchronized (lock) {for (char zimu : a) {System.out.println(zimu);
//
lock.notify();
try {lock.wait();
} catch (InterruptedException e) {e.printStackTrace();
}
}
}
}, "t1").start();}
3. 自旋锁 + volatile 实现
enum flag {T1,T2};
// 线程可见性
private static volatile flag r=flag.T1;
public static void main(String[] args) {char[] charsA=new char[]{'A','B','C','D'};
char[] charsB=new char[]{'1','2','3','4'};
new Thread(()->{for (char a:charsB){
// 无锁 自旋 首先 打印数字
// 只能应用 while 不能应用 if
while (r!=flag.T1){}
System.out.println(a);
r=flag.T2;
}
},"t1").start();
new Thread(()->{for (char a:charsA){while (r!=flag.T2){}
System.out.println(a);
r=flag.T1;
}
},"t2").start();}
-
lock 锁实现
ReentrantLock lock=new ReentrantLock(); char[] a="123456".toCharArray(); char[] b="ABCEFG".toCharArray(); // 条件判断 能够准确指定 那个线程先执行 Condition t1= lock.newCondition(); Condition t2= lock.newCondition(); new Thread(()->{lock.lock(); try {for (char v:a){System.out.println(v); t2.signal(); t1.await();} t2.signal();}catch (Exception ex){ex.printStackTrace(); }finally {lock.unlock(); } },"t1").start(); new Thread(()->{lock.lock(); try {for (char v:b){System.out.println(v); t1.signal(); t2.await();} t1.signal();}catch (Exception ex){ex.printStackTrace(); }finally {lock.unlock(); } },"t1").start();}
办法还是很多的..