解題思路
使用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工具
/**
* 掛起當(dāng)前線程漫试。(當(dāng)其許可可用時,恢復(fù)線程執(zhí)行誓焦,由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();
}
}
三悴能、總結(jié)
synchronized+線程notify/wait 方式在于喚醒隨機(jī)一個線程,而LockSupport可以控制喚醒哪個線程雳灾。
除此之外漠酿,LockSupport還支持設(shè)置線程是由什么對象阻塞的,在部分場景排查問題提供了幫助谎亩。
上面LockSupport的方法中在使用park方法都指定了blocker為一個子符串炒嘲,通過線程dump可以發(fā)現(xiàn) *** parking to wait for <0x00000000d7d97468> (a java.lang.String)*** 是由地址為0x00000000d7d97468的字符串阻塞的。
blocker.png
end
歡迎提供好的思路和指正問題匈庭,哈哈夫凸。