Lock接口示例
Lock 的挂起 await() 唤醒signal()
Lock 简单示例
public class LockDemo {
public static void main(String[] args) {
SaleTicket saleTicket = new SaleTicket();
new Thread(() -> {
for (int i = 1; i < 20; i++) {
saleTicket.sale();
}
}, "1号员工").start();
new Thread(() -> {
for (int i = 1; i < 20; i++) {
saleTicket.sale();
}
}, "2号员工").start();
new Thread(() -> {
for (int i = 1; i < 20; i++) {
saleTicket.sale();
}
}, "3号员工").start();
}
}
class SaleTicket {
private int number = 20;
private Lock lock = new ReentrantLock();
public void sale() {
lock.lock();//一进入就上锁
try {
if (number > 0) {
System.out.println(Thread.currentThread().getName() + "\t 卖出" + number-- + "号票\t还剩" + number);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();//最后一定要解锁
}
}
}
结果:
1号员工 卖出20号票 还剩19
1号员工 卖出19号票 还剩18
1号员工 卖出18号票 还剩17
1号员工 卖出17号票 还剩16
1号员工 卖出16号票 还剩15
1号员工 卖出15号票 还剩14
1号员工 卖出14号票 还剩13
1号员工 卖出13号票 还剩12
1号员工 卖出12号票 还剩11
1号员工 卖出11号票 还剩10
1号员工 卖出10号票 还剩9
1号员工 卖出9号票 还剩8
1号员工 卖出8号票 还剩7
1号员工 卖出7号票 还剩6
1号员工 卖出6号票 还剩5
1号员工 卖出5号票 还剩4
1号员工 卖出4号票 还剩3
3号员工 卖出3号票 还剩2
3号员工 卖出2号票 还剩1
2号员工 卖出1号票 还剩0
推荐启动线程的方式
第一种:匿名内部类
/*new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 20; i++) {
ticket.sale();
}
}
}, "AA").start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 20; i++) {
ticket.sale();
}
}
}, "BB").start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 20; i++) {
ticket.sale();
}
}
}, "CC").start();
*/
第二种:lombda表达式
new Thread(() -> {
for (int i = 1; i < 20; i++) {
saleTicket.sale();
}
}, "1号员工").start();
new Thread(() -> {
for (int i = 1; i < 20; i++) {
saleTicket.sale();
}
}, "2号员工").start();
new Thread(() -> {
for (int i = 1; i < 20; i++) {
saleTicket.sale();
}
}, "3号员工").start();
实现线程通信 一个生产 一个消费
public class Test02 {
public static void main(String[] args) {
shareDataOne shareDataOne = new shareDataOne();
new Thread(() -> {
for (int i = 0; i <= 10; i++) {
shareDataOne.incr();
}
}, "AA").start();
new Thread(() -> {
for (int i = 0; i <= 10; i++) {
shareDataOne.decr();
}
}, "BB").start();
new Thread(() -> {
for (int i = 0; i <= 10; i++) {
shareDataOne.incr();
}
}, "CC").start();
new Thread(() -> {
for (int i = 0; i <= 10; i++) {
shareDataOne.decr();
}
}, "DD").start();
}
}
class shareDataOne {
private int number = 0;
private Lock lock = new ReentrantLock();
private Condition cd = lock.newCondition();
public void incr() {
lock.lock();
try {
while (number != 0) {
cd.await();
}
number++;
System.out.println(Thread.currentThread().getName() + "\t" + number);
cd.signalAll();//此处唤醒用ALL避免死锁
} catch (Exception e) {
} finally {
lock.unlock();
}
}
public void decr() {
lock.lock();
try {
while (number == 0) {
cd.await();
}
number--;
System.out.println(Thread.currentThread().getName() + "\t" + number);
cd.signalAll();//此处唤醒用ALL避免死锁
} catch (Exception e) {
} finally {
lock.unlock();
}
}
}
Lock接口示例的更多相关文章
- Java多线程(五) Lock接口,ReentranctLock,ReentrantReadWriteLock
在JDK5里面,提供了一个Lock接口.该接口通过底层框架的形式为设计更面向对象.可更加细粒度控制线程代码.更灵活控制线程通信提供了基础.实现Lock接口且使用得比较多的是可重入锁(Reentrant ...
- java多线程Lock接口简介使用与synchronized对比 多线程下篇(三)
前面的介绍中,对于显式锁的概念进行了简单介绍 显式锁的概念,是基于JDK层面的实现,是接口,通过这个接口可以实现同步访问 而不同于synchronized关键字,他是Java的内置特性,是基于JVM的 ...
- Lock接口和ReadWriteLock接口
Lock接口 Lock接口在java.util.concurrent.locks包中,在jdk1.5之后才有. Lock接口有6个方法: void lock(); void lockInterrupt ...
- 并发王者课-铂金1:探本溯源-为何说Lock接口是Java中锁的基础
欢迎来到<并发王者课>,本文是该系列文章中的第14篇. 在黄金系列中,我们介绍了并发中一些问题,比如死锁.活锁.线程饥饿等问题.在并发编程中,这些问题无疑都是需要解决的.所以,在铂金系列文 ...
- php中创建和调用webservice接口示例
php中创建和调用webservice接口示例 这篇文章主要介绍了php中创建和调用webservice接口示例,包括webservice基本知识.webservice服务端例子.webservi ...
- synchronized关键字,Lock接口以及可重入锁ReentrantLock
多线程环境下,必须考虑线程同步的问题,这是因为多个线程同时访问变量或者资源时会有线程争用,比如A线程读取了一个变量,B线程也读取了这个变量,然后他们同时对这个变量做了修改,写回到内存中,由于是同时做修 ...
- 线程同步 Lock接口
同步:★★★★★ 好处:解决了线程安全问题. 弊端:相对降低性能,因为判断锁需要消耗资源,产生了死锁. 定义同步是有前提的: 1,必须要有两个或者两个以上的线程,才需要同步. 2,多个线程必须保证使用 ...
- Java基础知识强化之多线程笔记06:Lock接口 (区别于Synchronized块)
1. 简介 我们讲到了如何使用关键字synchronized来实现同步访问.本文我们继续来探讨这个问题,从Java 5之后,在java.util.concurrent.locks包下提供了另外一种方式 ...
- jdk1.5多线程Lock接口及Condition接口
jdk1.5多线程的实现的方式: jdk1.5之前对锁的操作是隐式的 synchronized(对象) //获取锁 { } //释放锁 jdk1.5锁的操作是显示的:在包java.util.concu ...
随机推荐
- Eclipse安装AmaterasUML插件问题
为了画UML图,我想在Eclipse(版本Version: Oxygen Release (4.7.0))安装AmaterasUML,第一步,安装GEF - http://download.eclip ...
- Vue+Java+Base64实现条码解析
前端部分(Vue + Vant) 引入Vant.使用Vant中的Uploader组件上传文件(支持手机拍照) import Vue from 'vue'; import { Uploader } fr ...
- Github 个人首页的 README,这样玩儿~
本文首发于 Ficow Shen's Blog,原文地址: Github 个人首页的 README,这样玩儿~. 内容概览 前言 创建仓库 修改 README 的内容 总结 前言 大家最近有没有发现这 ...
- JVM学习(七)JMM内存模型
一.什么是JMM 概念:Java内存模型(Java Memory Model ,JMM)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下对内存的访问都能 ...
- kubeadm单集群部署k8s1.15.1&calico网络
说明 本次实验在Windows下的VMware进行 系统配置及初始化配置在所有的主机执行 容器镜像全部替换为国内可拉取的 pod网络采用calico 实验环境 主机名 IP地址 角色 OS CPU/M ...
- Kafka和RocketMQ底层存储之那些你不知道的事
大家好,我是yes. 我们都知道 RocketMQ 和 Kafka 消息都是存在磁盘中的,那为什么消息存磁盘读写还可以这么快?有没有做了什么优化?都是存磁盘它们两者的实现之间有什么区别么?各自有什么优 ...
- tornado-简介和原理
tornado-设计初衷 1. 追求小而精 2. epoll IO多路复用和协程 3. 支持WebSocket 4. 单线程程序(GIL限制,本身某种意义上不启动多进程就是单线程程序) # Pytho ...
- Centos-归档文件或目录-tar
tar 对文件或者目录进行打包归档成一个文件,不是压缩 相关选项 -c 新建文件 -r 将目标文件追加都档案文件末尾 -t 列出归档文件中已经归档文件列表 -x 从归档文件中还原文件 -u 新文件更新 ...
- 小白也能看懂的Redis教学基础篇——朋友面试被Skiplist跳跃表拦住了
各位看官大大们,双节快乐 !!! 这是本系列博客的第二篇,主要讲的是Redis基础数据结构中ZSet(有序集合)底层实现之一的Skiplist跳跃表. 不知道那些是Redis基础数据结构的看官们,可以 ...
- Machine Learning-特征工程之特征选择
特征工程之特征选择 目录 简介 1 Filter(过滤式选择) 1.1 移除低方差特征(variance threshold) 1.2 信息增益(information gain) 1.3 单变量特征 ...