多线程如何循环顺序打印“ABABAB”
2020-07-26 本文已影响0人
超人也害羞
解题思路
使用synchronized和线程notify/wait
使用LockSupport
一、synchronized+线程notify/wait
public class TestLockSupport {
static Thread t1 = null;
static Thread t2 = null;
public static void main(String[] args) {
useThread();
}
private static void useThread() {
int times = 100;
t1 = new Thread("测试线程-1") {
@Override
public void run() {
for (int i = 0; i < times; i++) {
synchronized (TestLockSupport.class) {
try {
System.out.println("A");
TestLockSupport.class.notify();
TestLockSupport.class.wait();
} catch (InterruptedException e) {
}
}
}
}
};
t2 = new Thread("测试线程-2") {
@Override
public void run() {
for (int i = 0; i < times; i++) {
synchronized (TestLockSupport.class) {
try {
System.out.println("B");
TestLockSupport.class.notify();
TestLockSupport.class.wait();
} catch (InterruptedException e) {
}
}
}
}
};
t1.start();
t2.start();
}
}
二、LockSupport工具
/**
* 挂起当前线程。(当其许可可用时,恢复线程执行,由unpark()唤醒)
*/
public static void park() {
UNSAFE.park(false, 0L);
}
/**
* 通知指定线程其许可证可用(也可以说唤醒指定线程)。
*/
public static void unpark(Thread thread) {
if (thread != null)
UNSAFE.unpark(thread);
}
public class TestLockSupport {
static Thread t1 = null;
static Thread t2 = null;
public static void main(String[] args) {
int times = 100000;
String tmp = "abc";
String tmp2 = "efg";
t1 = new Thread("测试线程-1") {
@Override
public void run() {
for (int i = 0; i < times; i++) {
try {
Thread.sleep(1000L);
System.out.println("A");
} catch (InterruptedException e) {
}
LockSupport.unpark(t2);
LockSupport.park(tmp);
}
}
};
t2 = new Thread("测试线程-2") {
@Override
public void run() {
for (int i = 0; i < times; i++) {
LockSupport.park(tmp2);
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
}
System.out.println("B");
LockSupport.unpark(t1);
}
}
};
t1.start();
t2.start();
}
}
三、总结
synchronized+线程notify/wait 方式在于唤醒随机一个线程,而LockSupport可以控制唤醒哪个线程。
除此之外,LockSupport还支持设置线程是由什么对象阻塞的,在部分场景排查问题提供了帮助。
上面LockSupport的方法中在使用park方法都指定了blocker为一个子符串,通过线程dump可以发现 *** parking to wait for <0x00000000d7d97468> (a java.lang.String)*** 是由地址为0x00000000d7d97468的字符串阻塞的。
end
欢迎提供好的思路和指正问题,哈哈。