LockSupport并发等待基本模型

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;
    }
}

转载于:https://my.oschina.net/weichou/blog/731707

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值