Java并发练习
1.按顺序打印ABC
三个线程,每个线程分别打印A,B,C各十次,现在要求按顺序输出A,B,C
package concurrency; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class 按顺序打印ABC { public static void main(String[] args) {
ExecutorService threadPool = Executors.newFixedThreadPool(3);
Object lockA = new Object();
Object lockB = new Object();
Object lockC = new Object();
Runnable rA = new OrderPrintABC(lockC, lockA, "A");
Runnable rB = new OrderPrintABC(lockA, lockB, "B");
Runnable rC = new OrderPrintABC(lockB, lockC, "C");
threadPool.execute(rA);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
threadPool.execute(rB);
threadPool.execute(rC);
threadPool.shutdown();
} private static class OrderPrintABC implements Runnable{ private Object preLock;
private Object selfLock;
private String taskName;
private int count = 10; public OrderPrintABC(Object preLock, Object selfLock, String taskName) {
this.preLock = preLock;
this.selfLock = selfLock;
this.taskName = taskName;
} @Override
public void run() {
while(count > 0) {
synchronized(preLock) {
synchronized(selfLock) {
System.out.print(taskName);
count--;
selfLock.notifyAll();
}
if(count > 0) {
try {
preLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
}
2. 生产者消费者: 要尽量使用BlockingQueue来实现
https://github.com/CyC2018/CS-Notes/blob/master/notes/Java%20%E5%B9%B6%E5%8F%91.md#blockingqueue
package concurrency; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class 生产者消费者 { //有界队列
private static class BoundQueue<T> {
private Object[] items;
private int count = 0;
private Lock lock = new ReentrantLock();
private Condition notEmpty = lock.newCondition();
private Condition notFull = lock.newCondition(); public BoundQueue(int size) {
items = new Object[size];
} public void add(T t) throws InterruptedException {
lock.lock();
try {
Long nano = 0L;
while (count == items.length) {
if(nano < 0L) {
return;
};
System.out.println("仓库已满");
notFull.awaitNanos(5000);
}
items[count++] = t;
System.out.println("生产者放入" + t);
notEmpty.signal();
Thread.sleep(1000);
} finally {
lock.unlock();
}
} public T remove() throws InterruptedException {
lock.lock();
T t;
try {
Long nano = 0L;
while (count == 0) {
if(nano < 0L) {
return null;
};
System.out.println("仓库已空");
nano = notEmpty.awaitNanos(5000);
}
t = (T) items[count - 1];
items[--count] = null;
System.out.println("消费者接收" + t);
notFull.signal();
Thread.sleep(1000);
} finally {
lock.unlock();
}
return t;
}
} //生产者
private static class Product implements Runnable{
private BoundQueue queue;
private int count; public Product (BoundQueue queue, int count) {
this.queue = queue;
this.count = count;
} public void run() {
int itr = 1;
while(itr <= count) {
try {
queue.add(itr);
itr++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} //消费者
private static class Consumer implements Runnable{
private BoundQueue queue;
private int count; public Consumer(BoundQueue queue, int count) {
this.queue = queue;
this.count = count;
} @Override
public void run() {
int itr = 0;
while(itr <= count) {
try {
queue.remove();
itr++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} public static void main(String[] args) {
BoundQueue<Integer> queue = new BoundQueue<>(5);
int count = 6;
Runnable rP = new Product(queue, count);
Runnable rC = new Consumer(queue, count);
ExecutorService threadPool = Executors.newFixedThreadPool(2);
threadPool.execute(rP);
threadPool.execute(rC);
threadPool.shutdown();
}
}
https://github.com/CyC2018/CS-Notes/blob/master/notes/Java%20%E5%B9%B6%E5%8F%91.md#blockingqueue
Java并发练习的更多相关文章
- 多线程的通信和同步(Java并发编程的艺术--笔记)
1. 线程间的通信机制 线程之间通信机制有两种: 共享内存.消息传递. 2. Java并发 Java的并发采用的是共享内存模型,Java线程之间的通信总是隐式执行,通信的过程对于程序员来说是完全透 ...
- 【Java并发编程实战】----- AQS(四):CLH同步队列
在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头 ...
- 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport
在上篇博客([Java并发编程实战]----- AQS(二):获取锁.释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起:在释放锁后,需要唤醒该线程的继任节点 ...
- 【Java并发编程实战】----- AQS(二):获取锁、释放锁
上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...
- 【Java并发编程实战】-----“J.U.C”:CLH队列锁
在前面介绍的几篇博客中总是提到CLH队列,在AQS中CLH队列是维护一组线程的严格按照FIFO的队列.他能够确保无饥饿,严格的先来先服务的公平性.下图是CLH队列节点的示意图: 在CLH队列的节点QN ...
- 【Java并发编程实战】-----“J.U.C”:CountDownlatch
上篇博文([Java并发编程实战]-----"J.U.C":CyclicBarrier)LZ介绍了CyclicBarrier.CyclicBarrier所描述的是"允许一 ...
- 【Java并发编程实战】-----“J.U.C”:CyclicBarrier
在上篇博客([Java并发编程实战]-----"J.U.C":Semaphore)中,LZ介绍了Semaphore,下面LZ介绍CyclicBarrier.在JDK API中是这么 ...
- 【Java并发编程实战】-----“J.U.C”:ReentrantReadWriteLock
ReentrantLock实现了标准的互斥操作,也就是说在某一时刻只有有一个线程持有锁.ReentrantLock采用这种独占的保守锁直接,在一定程度上减低了吞吐量.在这种情况下任何的"读/ ...
- Java并发编程:volatile关键字解析
Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...
- JAVA并发编程J.U.C学习总结
前言 学习了一段时间J.U.C,打算做个小结,个人感觉总结还是非常重要,要不然总感觉知识点零零散散的. 有错误也欢迎指正,大家共同进步: 另外,转载请注明链接,写篇文章不容易啊,http://www. ...
随机推荐
- Fragment学习
利用Fragment可以动态的加载页面,减少Activity的数量. 便于开发 类似与html中FragmentSet一样 嵌套在一起,使每个页面为独立的 代码如下: package com.exam ...
- git fork , git pull request那回事
git fork 原理 相当于你在原项目的主分支上又建立了一个分支,你可以在该分支上任意修改,如果想将你的修改合并到原项目中时,可以pull request,这样原项目的作者就可以将你修改的东西合并到 ...
- ROS开源小车TurtleBot3详情介绍(Burger)
您为什么要选择ROS开源智能小车 ROS(RobotOperating System,机器人操作系统)是目前世界上更主流更多人使用的的机器人开源操作系统.它可以提供操作系统应有的服务,包括硬件抽象,底 ...
- HarmonyOS(LiteOs_m) 官方例程移植到STM32初体验
HarmonyOS(LiteOs_m) 官方例程移植到STM32初体验 硬件平台 基于正点原子战舰V3开发板 MCU:STM32F103ZET6 片上SRAM大小:64KBytes 片上FLASH大小 ...
- Docker部署&MySQL部署
Docker部署 本文采用的是阿里云的centos7 # 更新yum yum update # 安装docker yum install docker # 启动docker systemctl sta ...
- 建立索引和创建视图(结合YGGL.sql)
一.请按要求对YGGL库建立相关索引 (1)使用create index 语句创建索引 1.对employees表中的员工部门号创建普通索引depart_ind. mysql> create i ...
- NOIP初赛篇——02计算机系统的基本结构
引言 计算机系统由硬件和软件两部分组成,硬件系统是计算机的"躯干",是物质基础.而软件系统则是建立在这个"躯干"上的"灵魂". 计算机硬件 ...
- Docusaurus2 快速建站,发布 GitHub Pages
Docusaurus2 可快速搭建文档.博客.官网等网站,并发布到 GitHub Pages, Serverless 等. 我们只需 Markdown 写写内容就行,也可直接编写 React 组件嵌入 ...
- 牛客网NC15二叉树的层次遍历
题目 给定一个二叉树,返回该二叉树层序遍历的结果,(从左到右,一层一层地遍历) 例如: 给定的二叉树是{3,9,20,#,#,15,7}, 该二叉树层序遍历的结果是 [ [3], [9,20], [1 ...
- Lniux 入门:03 用户及文件权限管理
1.1 实验内容 Linux 中创建.删除用户,及用户组等操作. Linux 中的文件权限设置. 1.2 实验知识点 Linux 用户管理 Linux 权限管理 通过第一节课程的学习,你应该已经知道, ...