文档章节

LockSupport并发等待基本模型

中成才
 中成才
发布于 2016/08/12 12:36
字数 470
阅读 62
收藏 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
显式锁(java.util.Concurrent)

一、前言   在分析完了集合框架后,很有必要接着分析java并发包下面的源码,JUC(java.util.concurrent)源码也是我们学习Java迈进一步的重要过程。我们分为几个模块进行分析,首先是对锁模...

狼王黄师傅
11/27
0
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
JUC 基础内容概述

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

暗之幻影
2016/12/17
35
0

没有更多内容

加载失败,请刷新页面

加载更多

Caffe(二)-Python-自定义网络

这里我们用一个例子先来体验一下 首先定义一下我们的环境变量 $PYTHONPATH,我这儿是Windows开发环境,至于Windows Caffe怎么编译由读者自己下去搞定 我使用的控制台是 Windows PowerShell 添...

Pulsar-V
38分钟前
3
0
ActiveMQ从入门到精通(二)之可靠性机制

ActiveMQ的可靠性机制 缘由( 确认JMS消息) 只要消息被确认之后,才认为消息被成功消费了。消息的成功消费包括三个阶段:客户端接收消息、客户端处理消息以及客户端确认消息。在事务性会话中...

一看就喷亏的小猿
46分钟前
1
0
源码分析 Mybatis 的 foreach 为什么会出现性能问题

背景 最近在做一个类似于综合报表之类的东西,需要查询所有的记录(数据库记录有限制),大概有1W条记录,该报表需要三个表的数据,也就是根据这 1W 个 ID 去执行查询三次数据库,其中,有一...

TSMYK
今天
7
0
IC-CAD Methodology企业实战之openlava

在云计算解决安全问题并成为IC界主流运算平台之前,私有的服务器集群系统仍然是各大IC公司的计算资源平台首选。 现在主流的服务器集群管理系统包括lsf,openlava,SkyForm,三者都属于lsf一系...

李艳青1987
今天
7
0
http response stream 字节流 接收与解码

在接收图片、音频、视频的时候,需要用到二进制流。 浏览器会发给客户端 字节Byte流,一串串的发过来_int8格式 -128~127(十进制),也就是8bit(位)。 客户端接收的时候,对接收到的字节收集,...

大灰狼wow
今天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部