文档章节

LockSupport并发等待基本模型

中成才
 中成才
发布于 2016/08/12 12:36
字数 470
阅读 60
收藏 1

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

© 著作权归作者所有

共有 人打赏支持
中成才
粉丝 51
博文 125
码字总数 43471
作品 0
海淀
架构师
Java并发编程序列之JUC中Condition线程通讯

Java并发编程序列之JUC中Condition线程通讯 Hello,大家好,前面给大家讲解synchronized关键字时给大家讲了下线程间的通讯,wait和notify.这两个API都是定义在Object中的方法,今天要给大家讲...

2017/12/28
0
0
JUC 基础内容概述

Concurrent Programming in Java 的作者 Doug Lea 编写了一个极其优秀的、免费的并发实用程序包,它包括并发应用程序的锁、互斥、队列、线程池、轻量级任务、有效的并发集合、原子的算术操作...

暗之幻影
2016/12/17
35
0
深入学习Lock锁(2)——LockSupport工具类

在同步组件中,当需要阻塞或唤醒一个线程的时候,都会使用LockSupport工具类来完成相应 工作。LockSupport定义了一组的公共静态方法,这些方法提供了最基本的线程阻塞和唤醒功能,而LockSup...

江左煤郎
05/24
0
0
浅谈Java并发编程系列(八)—— LockSupport原理剖析

LockSupport 用法简介 LockSupport 和 CAS 是Java并发包中很多并发工具控制机制的基础,它们底层其实都是依赖Unsafe实现。 LockSupport是用来创建锁和其他同步类的基本线程阻塞原语。LockSup...

codershamo
2017/02/21
0
0
[高并发Java 五] JDK并发包1

在[高并发Java 二] 多线程基础中,我们已经初步提到了基本的线程同步操作。这次要提到的是在并发包中的同步控制工具。 1. 各种同步控制工具的使用 1.1 ReentrantLock ReentrantLock感觉上是s...

Hosee
2016/01/21
6.4K
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

c语言之内存分配笔记

先看一个数组: short array[5] = {1,2} // 这儿定义的一个int类型的数组,数组第1和第2个元素值是1和2.其余后面默认会给值为0; 或者 short array[] = {1,2};//这儿数组第1和第2个元素,数组...

DannyCoder
今天
2
0
Shell | linux安装包不用选择Y/N的方法

apt-get install -y packageOR echo "y" | sudo apt-get install package

云迹
今天
2
0
Hadoop的大数据生态圈

基于Hadoop的大数据的产品圈 大数据产品的一句话概括 Apache Hadoop: 是Apache开源组织的一个分布式计算开源框架,提供了一个分布式文件系统子项目(HDFS)和支持MapReduce分布式计算的软件架...

zimingforever
今天
5
0
八大包装类型的equals方法

先看其中一个源码 结论:八大包装类型的equals方法都是先判断类型是否相同,不相同则是false,相同则判断值是否相等 注意:包装类型不能直接用==来等值比较,否则编译报错,但是数值的基本类型...

xuklc
今天
2
0
NoSQL , Memcached介绍

什么是NoSQL 非关系型数据库就是NoSQL,关系型数据库代表MySQL 对于关系型数据库来说,是需要把数据存储到库、表、行、字段里,查询的时候根据条件一行一行地去匹配,当量非常大的时候就很耗...

TaoXu
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部