经典面试题:俩线程交替打印数字字母 例如: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(); }
SynchronousQueue 必须消费 容量为0
//同步队列 容量为0 必须消费 SynchronousQueue<Object> queue1 = new SynchronousQueue<>(); SynchronousQueue<Object> queue2 = new SynchronousQueue<>(); char[] chars = {'1', '2', '3', '4', '5'}; char[] zim = {'A', 'B', 'C', 'D', 'F'}; new Thread(() -> { for (char c : zim) { try { System.out.println(queue2.take()); queue1.put(c); } catch (InterruptedException e) { e.printStackTrace(); } } }, "t1").start(); new Thread(() -> { for (char c : chars) { try { queue2.put(c); System.out.println(queue1.take()); } catch (InterruptedException e) { e.printStackTrace(); } } }, "t2").start(); }
方法还是很多的..
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。