lock 线程 java_JAVA多线程-基础Lock Condition 并发集合

跟上一篇文章比较,这次改进了之前的代码,使用了Lock Condition 和并发集合.代码量减了一些,并且更加容易读了.

这篇代码是上一篇的改进版,逻辑在前篇有说明,以防大家看不到,我再重现贴一遍.后续会使用高阶的线程工具再次改进,以求代码更简单.代码的逻辑:

1)SProducer不停的产生number到queue中.

2)3个carrier不停的取出queue中的number.

3)如果queue中存在10个剩余number时,SProducer会停下来等Carrier消费一些后再生产.

4)如果Carrier发现queue中没有number时,会等待.

5)如果Carrier取出的数字末尾为4, 则会挑起罢工事件.

6)Carrier罢工会引发一个Negotiation线程进行谈判.

7)罢工阶段SProducer和所有Carrier均停工.

8)Negotiation如果发现取出的number首位为3或者7,将引发谈判失败.

9)如果谈判成功,则恢复工作,如果谈判失败,则破产,所有线程均退出.

注意:使用lock的时候一定要注意, lock()和unlock()方法一定要成对出现. 最好放到try{}finally{}中,这样,unlock()方法必会调到.倘若没有使用unlock()就return了,会导致线程死锁.

package concurrency;

import java.util.ArrayList;

import java.util.concurrent.ArrayBlockingQueue;

import java.util.concurrent.locks.Condition;

import java.util.concurrent.locks.ReentrantLock;

public class Producer extends Thread {

private final static ArrayBlockingQueue numbers = new ArrayBlockingQueue(10);

private final static ArrayList threads = new ArrayList();

private volatile boolean negotiating = false;

private ReentrantLock negotiationLock = new ReentrantLock();

private Condition negotiationCondition = negotiationLock.newCondition();

private class Negotiation implements Runnable {

private String number;

private Negotiation(String number) {

this.number = number;

}

public void run() {

try {

System.out.println("Start negotiation...");

sleep(5000);

if (number.startsWith("7") || number.startsWith("3")) {

System.out.println("Negotiation broken.");

for (Thread t : threads) {

t.interrupt();

}

System.out.println("Negotiation broken post handle.");

return;

}

System.out.println("Negotiation succeeds.");

} catch (InterruptedException e) {

System.out.println("Middle man is killed.");

}

negotiationLock.lock();

negotiating = false;

negotiationCondition.signalAll();

negotiationLock.unlock();

}

}

private class Carrier implements Runnable {

private String name;

private Carrier(String name) {

this.name = name;

}

public void run() {

while(true) {

try{

negotiationLock.lock();

while(negotiating) {

try {

System.out.println("Carrier ["+name+"] join stricks.");

negotiationCondition.await();

} catch (InterruptedException e) {

System.out.println("Negotiation fails. Carrier [" + name + "] retires.");

return;

}

}

} finally {

negotiationLock.unlock();

}

String number;

try {

number = numbers.take();

System.out.println("Carrier [" + name + "] carries "+ number +" out of List;");

} catch (InterruptedException e1) {

System.out.println("Negotiation fails. Carrier [" + name + "] retires.");

return;

}

if (number.endsWith("4")) {

try {

negotiationLock.lock();

while (negotiating) {

try {

negotiationCondition.await();

} catch (InterruptedException e) {

System.out.println("Negotiation fails. Carrier [" + name + "] retires.");

return;

}

}

negotiating = true;

System.out.println("Stricks happen on number:"+number);

new Thread(new Negotiation(number)).start();

} finally {

negotiationLock.unlock();

}

}

}

}

}

public void run() {

Thread a = new Thread(new Carrier("a"));

Thread b = new Thread(new Carrier("b"));

Thread c = new Thread(new Carrier("c"));

threads.add(this);

threads.add(a);

threads.add(b);

threads.add(c);

a.start();

b.start();

c.start();

this.produceNumbers();

}

private void produceNumbers() {

while (true) {

while(negotiating) {

negotiationLock.lock();

try {

System.out.println("Stricking... Producer waiting for negotiation result.");

negotiationCondition.await();

System.out.println("Negotiation succeeds. Producer happy.");

} catch (InterruptedException e) {

System.out.println("Negotiation fails. Producer breaks up.");

return;

} finally {

negotiationLock.unlock();

}

}

String number = ""+new java.util.Random().nextInt(47);

try {

numbers.put(number);

System.out.println("Produce number " + number + " into List;");

} catch (InterruptedException e) {

System.out.println("Negotiation fails. Producer breaks up.");

return;

}

}

}

public static void main(String[] args) {

new Producer().start();

}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/536867.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mycat mysql ha 方案_7、基于 HA 机制的 Mycat 高可用--mycat

在实际项目中,Mycat 服务也需要考虑高可用性,如果 Mycat 所在服务器出现宕机,或 Mycat 服务故障,需要有备机提供服务,需要考虑 Mycat 集群。1、 高可用方案使用 HAProxy Keepalived 配合两台 Mycat 搭起 Mycat 集群&a…

爬虫scrapy模块

首先下载scrapy模块 这里有惊喜 https://www.cnblogs.com/bobo-zhang/p/10068997.html 创建一个scrapy文件 首先在终端找到一个文件夹 输入 scrapy startproject jy (项目件名) 修改setting文件配置 # Crawl responsibly by identifying yourself (and your website) on the us…

python canvas画移动物体_如何实现Canvas图像的拖拽、点击等操作

上一篇Canvas的博文写完后,有位朋友希望能对Canvas绘制出来的图像进行点击、拖拽等操作,因为Canvas绘制出的图像能很好的美化。好像是想做炉石什么的游戏,我也没玩过。Canvas在我的理解中就好像在一张画布上绘制图像,它只能看到却…

Git基础知识教程整理(Git基本操作)

Git简介 Git是目前世界上最先进的分布式版本控制系统(没有之一)。Linux之父Linux用C语言写了Git分布式版本控制系统。 分布式版本控制系统与集中式版本控制系统的区别 区别分布式集中式中央服务器有,版本库集中存放在中央服务器,工…

python plot map_使用matplotlibbasemap在边界打印

我在绘制多边形时遇到了困难,例如,在使用matplotlib basemap生成的地图边界上绘制多边形。在下面的示例中,地图边界由日期线指定。我试图通过指定三角形顶点的坐标来绘制一个跨越日期线的三角形。当所有的坐标都在地图内时,这种方…

SQL查询语句 group by后, 字符串合并

合并列值 --******************************************************************************************* 表结构,数据如下: id value ----- ------ aa bb aaa bbb ccc 需要得到结果: id values ------ ----------- aa,bb aaa…

Git 基础 —— 常用命令

Git 基础学习系列 Git 基础 —— 安装 配置 别名 对象Git 基础 —— 常用命令Git 基础 —— 常见使用场景Git基础 —— Github 的使用git init 创建 Git 本地仓库 远端无仓库,本地无仓库,本地新建一个仓库 git init git_learning 远端有仓库,…

python安装caffe_Linux下caffe的安装

下载caffe并保存到一个目录下(推荐放到 /home 目录)安装依赖项:sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libhdf5-serial-dev protobuf-compilersudo apt-get install --no-install-recommends libboost-all-devsudo apt-…

linux 访问Windows 共享文件的方法

2019独角兽企业重金招聘Python工程师标准>>> 1 安装Samba服务 2 启动 samba服务 /etc/init.d/smb restart 3 安装插件 cifs解决只读挂载:yum install cifs-utils.x86_64 4 在windows下共享一个可以用的文件夹 5 将 windows 共享文件夹挂载到linux上 命令…

基于Blink构建亲听项目以及全链路debug项目实时响应能力

案例与解决方案汇总页:阿里云实时计算产品案例&解决方案汇总 本文全面总结了大数据项目组在亲听项目以及全链路debug项目上进行的实时流处理需求梳理,架构选型,以及达成效果 一、背景介绍 1.1亲听项目 亲听项目专注于帮助用户收集、展示、…

python的重点_python知识点

"""author:lei"""import os#os.path.join() 将分离的部分合成一个整体filenameos.path.join(/home/ubuntu/python_coding,split_func)print filename#输出为:/home/ubuntu/python_coding/split_func#os.path.splitext()将文件名和扩展…

在既有系统中打通Apache Ignite、MySQL和Node.js

为什么80%的码农都做不了架构师?>>> 介绍 在本系列的第一篇文章中,安装了Node.js、Ignite的Node.js瘦客户端包,并且测试了一个示例应用。在本文中,可以看一下Ignite在处理其它数据源(比如关系数据库&#…

java hashmap 的api_JAVA基础--JAVA API集合框架(ArrayList、HashSet、HashMap使用)

一、集合Collection1. 集合介绍变量:表示的内存中的一个空间,只能保存确定类型的单个数据数组:表示的是内存中的多个连续的空间,这些空间中可以存储多个同类型的数据。后期继续学习面向对象技术,我们在程序中开始创建对…

Vue进阶知识笔记

利用v-for循环出的多个li标签&#xff0c;点击不同的li变换颜色 方法一 <ul v-for"(item,index) in list" :key"index" class"details"><li ref"lisd" click"faillist(index)" :class"{active:ind index}&qu…

teamcity mysql 配置_CentOS 7 上 TeamCity 安装

CentOS 7 上 TeamCity 安装非入门教程, 初次接触centos/docker的朋友需要谨慎一. 安装 MySQL为了后续的需要, 这里安装了 Docker, 当然如果你已经有了 MySQL 或者其它推荐的数据库[MySQL, PostgreSQL, Oracle, MS SQL], 则可忽略1. 安装 Docker补充:# 启动dockersudo systemctl…

Python网络请求库Requests,妈妈再也不会担心我的网络请求了(二)

本文同步发表于我的微信公众号&#xff0c;扫一扫文章底部的二维码或在微信搜索 极客导航 即可关注&#xff0c;每个工作日都有文章更新。 一、概况 接着上篇说&#xff0c;如果你真以为Requests网络请求库只有Get请求和Post请求&#xff0c;那就大错特错了。它还一些其他用法&…

dbunit java_java - 错误地抛出了Java DBUnit AmbiguousTableNameException - 堆栈内存溢出

我正在尝试DBUnit(2.6.0)&#xff0c;我正在尝试导出我的完整数据库(PostgreSQL)。 但是抛出以下异常&#xff1a;线程“main”中的异常org.dbunit.database.AmbiguousTableNameException&#xff1a;FLYWAY_SCHEMA_HISTORY这是正确的行为&#xff0c;因为我有两个具有相同名称…

Docker 命令详解(run篇)

参考&#xff1a;https://www.cnblogs.com/yfalcon/p/9044246.html 命令格式&#xff1a;docker run [OPTIONS] IMAGE [COMMAND] [ARG...]Usage: Run a command in a new container中文意思为&#xff1a;通过run命令创建一个新的容器&#xff08;container&#xff09; 常用选…

java 同步 lock_关于java:同步是否像Lock.lock()一样驻留并发线程?

当我们调用lock.lock()或尝试输入synchronized块时&#xff0c;如果其他某个线程已经获得了该锁&#xff0c;则我们的线程将阻塞。 现在我的问题是&#xff0c;当我们查看lock.lock()的实现时&#xff0c;它会将获取锁委托给AQS&#xff0c;而AQS实际将当前线程驻留在该线程中(…

Idea项目中常见错误及笔记(Old)

1、Idea基础设置&#xff1a; File-->settings--> 1>修改字体&#xff1a;Font 2>修改编码格式&#xff1a;File Encodings(全部UTF-8,右下方复选框勾中--防止程序中的汉字转为ASCII码) 3>修改行号&#xff1a;Appearance&#xff1a;show line numbers show me…