【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
LockSupport并发等待基本模型。写的个测试,具体请看注释。
package test;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.LockSupport;
/**
* @author Wei.Chou(weichou2010@gmail.com)
* @version 1.0, 12/08/2016
*/
public class ParkTest {
private static volatile boolean resulted;
private static volatile boolean completed;
private static volatile boolean end0;
private static volatile boolean end1;
private static final AtomicInteger parkCount = new AtomicInteger(0);
private static final Set<Thread> set = new CopyOnWriteArraySet<>();
private static volatile Object result;
public static void main(String[] args) {
new Thread() {
@Override
public void run() {
int i = 0;
while (true) {
while (end0) Thread.yield();
System.out.println("thread started");
sync();
end0 = true;
System.out.println("thread end +++");
while (!end1) Thread.yield();
resulted = false;
completed = false;
System.out.println(">>>>>>>>>>>>>>>>>>>> thread +++ loop:" + i++ + ", parkCount:" + parkCount.get());
end1 = false;
}
}
}.start();
new Thread() {
@Override
public void run() {
int i = 0;
while (true) {
while (end1) Thread.yield();
System.out.println("thread1 started");
work();
end1 = true;
System.out.println("thread1 end ---");
while (!end0) Thread.yield();
System.out.println("<<<<<<<<<<<<<<<<<<<< thread1 --- loop:" + i++ + ", parkCount:" + parkCount.get());
set.clear();
end0 = false;
}
}
}.start();
}
private static Object sync() {
try {
Thread.sleep((int) (Math.random() * 100));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread sync calling");
final Thread t = Thread.currentThread();
set.add(t);
if (Math.random() < .5) {
Thread.yield();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
boolean unparked = false;
while (true) {
System.out.println("thread loop ~~~~~~~~~~~~~~~~~~~~~~~~~~~-parkCount:"
+ parkCount.get());
if (completed) {
if (set.contains(t)) {
set.remove(t);
} else {
System.out.println("thread park ###########################-parkCount:"
+ parkCount.incrementAndGet());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// parkCount.incrementAndGet();
// 消化掉那个unpark
if (!unparked) LockSupport.park();
}
return result;
} else if (resulted) { // 走这个case是因为很有可能在上面set.add(t)之前, 这个状态就已经设置了。
// 那么unpark()是在add(t)之前还是之后, 情况是随机的, 无从知晓。
// 但又不能总yield(), 如果状态没有设置, 不知道要等多久, 那么LockSupport.park()是最合适的。
//**********//
// 此时是个量子态,一切都不稳定,那就再来一遍。
// 但是这个状态的持续时间极短暂,因此yield()是理想方法。
Thread.yield();
} else {
System.out.println("thread park ???????????????????????????-parkCount:"
+ parkCount.incrementAndGet());
// parkCount.incrementAndGet();
// 没有得到结果,那就等着。
LockSupport.park();
// 保险起见, 再来一遍看看, 而不直接返回。
unparked = true;
}
}
}
private static void work() {
try {
System.out.println("thread1 working");
// work time
Thread.sleep((int) (Math.random() * 3000));
} catch (InterruptedException e) {
e.printStackTrace();
}
// 这里只修改结果,完成的标识放最后
result = new Object();
System.out.println("thread1 resulted");
resulted = true;
for (Thread t : set) {
System.out.println("thread1 unpark---------------------------parkCount:"
+ parkCount.decrementAndGet());
// parkCount.decrementAndGet();
LockSupport.unpark(t);
set.remove(t);
}
System.out.println("thread1 completed");
completed = true;
}
}
来源:oschina
链接:https://my.oschina.net/u/1864277/blog/731707