LockSupport并发等待基本模型

好久不见. 提交于 2019-12-23 10:11:15

【推荐】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;
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!