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. ...
随机推荐
- [leetcode]24. Swap Nodes in Pairs交换链表的节点
感觉这个题后台的运行程序有问题,一开始自己想的是反转链表那道题的方法,只是隔一个节点执行一次,但是没有通过,TLE了,但是很奇怪,并没有死循环,就是最后返回的时候超时. 最后的思路就是很简单的进行交换 ...
- CentOS8 下Nginx使用教程
1.nginx安装 dnf install nginx -y 2.nginx常用目录 nginx.conf目录:/etc/nginx.nginx.conf nginx启动目录:/usr/sbin/ng ...
- Pytest测试框架(一):pytest安装及用例执行
PyTest是基于Python的开源测试框架,语法简单易用,有大量的插件,功能非常多.自动检测测试用例,支持参数化,跳过特定用例,失败重试等功能. 安装 pip install -U pytest ...
- jq 右键菜单在弹出菜单前如果需要显示与否的判断相关操作
菜单插件(ContextMenu)接收一个额外的参数对象来设置菜单项的样式和绑定鼠标事件. 菜单插件(ContextMenu)支持一下参数设置: bindings 包含id的对象:函数组. 当关联的菜 ...
- elasticsearch基本概念和基本语法
Elasticsearch是基于Json的分布式搜索和分析引擎,是利用倒排索引实现的全文索引. 优势: 横向可扩展性:增加服务器可直接配置在集群中 分片机制提供更好的分布性:分而治之的方式来提升处理效 ...
- 万万没想到,面试中,连 ClassLoader类加载器 也能问出这么多问题…..
1.类加载过程 类加载时机 「加载」 将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在内存上创建一个java.lang.Class对象用来封装类在方法区内的数据 ...
- 【原创】X86_64汇编、寄存器、内嵌汇编
整理的X86_64/X86汇编.寄存器.C内嵌汇编笔记,主要用于查阅使用. 目录 一.汇编语言 二.指令 数据传输指令 栈操作指令 push pop 运算指令 位操作 比较操作指令 标志寄存器 流控制 ...
- Java 使用 mail.jar 实现邮件发送
目录 准备工作 使用到的 jar 包 实现代码 准备工作 要想实现邮件发送, 需要先打开发送邮箱的 POP3/SMTP 服务,打开方式在 设置>帐户 中去打开,打开之后如果是qq邮箱会获得一个授 ...
- C#实现一个弹窗监控小程序
一..实现弹窗淡入淡出等效果即弹窗自动关闭 技术要点: 1.弹窗效果(淡入淡出,自下而上滑入)使用WIN API实现 2.弹出的窗体在一定时间后,自动关闭使用一个timer实现,弹窗开始是,打开tim ...
- 登陆到 SAP 系统后的用户出口
增强类型:smod 增强名称:SUSR0001 组件(退出功能模块):EXIT_SAPLSUSF_001 功能:用户每次登陆SAP系统后都会调用这个SUSR0001增强,可以在FUNCTION EXI ...