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接口示例的更多相关文章

  1. Java多线程(五) Lock接口,ReentranctLock,ReentrantReadWriteLock

    在JDK5里面,提供了一个Lock接口.该接口通过底层框架的形式为设计更面向对象.可更加细粒度控制线程代码.更灵活控制线程通信提供了基础.实现Lock接口且使用得比较多的是可重入锁(Reentrant ...

  2. java多线程Lock接口简介使用与synchronized对比 多线程下篇(三)

    前面的介绍中,对于显式锁的概念进行了简单介绍 显式锁的概念,是基于JDK层面的实现,是接口,通过这个接口可以实现同步访问 而不同于synchronized关键字,他是Java的内置特性,是基于JVM的 ...

  3. Lock接口和ReadWriteLock接口

    Lock接口 Lock接口在java.util.concurrent.locks包中,在jdk1.5之后才有. Lock接口有6个方法: void lock(); void lockInterrupt ...

  4. 并发王者课-铂金1:探本溯源-为何说Lock接口是Java中锁的基础

    欢迎来到<并发王者课>,本文是该系列文章中的第14篇. 在黄金系列中,我们介绍了并发中一些问题,比如死锁.活锁.线程饥饿等问题.在并发编程中,这些问题无疑都是需要解决的.所以,在铂金系列文 ...

  5. php中创建和调用webservice接口示例

    php中创建和调用webservice接口示例   这篇文章主要介绍了php中创建和调用webservice接口示例,包括webservice基本知识.webservice服务端例子.webservi ...

  6. synchronized关键字,Lock接口以及可重入锁ReentrantLock

    多线程环境下,必须考虑线程同步的问题,这是因为多个线程同时访问变量或者资源时会有线程争用,比如A线程读取了一个变量,B线程也读取了这个变量,然后他们同时对这个变量做了修改,写回到内存中,由于是同时做修 ...

  7. 线程同步 Lock接口

    同步:★★★★★ 好处:解决了线程安全问题. 弊端:相对降低性能,因为判断锁需要消耗资源,产生了死锁. 定义同步是有前提的: 1,必须要有两个或者两个以上的线程,才需要同步. 2,多个线程必须保证使用 ...

  8. Java基础知识强化之多线程笔记06:Lock接口 (区别于Synchronized块)

    1. 简介 我们讲到了如何使用关键字synchronized来实现同步访问.本文我们继续来探讨这个问题,从Java 5之后,在java.util.concurrent.locks包下提供了另外一种方式 ...

  9. jdk1.5多线程Lock接口及Condition接口

    jdk1.5多线程的实现的方式: jdk1.5之前对锁的操作是隐式的 synchronized(对象) //获取锁 { } //释放锁 jdk1.5锁的操作是显示的:在包java.util.concu ...

随机推荐

  1. python爬取新浪财经

    我们来获取这里的title和url然后再获取这里面url的编辑作者 可以看到右边的几个就对应的左边不同的div .m-p1-mb2-list.m-list-container ul li a impo ...

  2. 被产品经理怼了,线上出Bug为啥你不知道

    前言 前几天跟读者聊天,他说被产品经理给怼了.原因是线上出 Bug 了,最后是客户反馈才知道的. 我就问他:你们是不是没做监控? 读者:我们是刚成立的创业团队,目前最重要的就是堆功能,很多基础设施都没 ...

  3. redis集群简介

    1.1        集群的概念 所谓的集群,就是通过添加服务器的数量,提供相同的服务,从而让服务器达到一个稳定.高效的状态. 1.1.1       使用redis集群的必要性 问题:我们已经部署好 ...

  4. 嵌入式arm-linux mips-linux 交叉编译GDB,结合vscode图形化调试使用,coredump定位段错误

    第一部分:使用GDB GDB源码下载路径:http://ftp.gnu.org/gnu/gdb/ 遇到的主要难点: 选择合适的GDB源码版本 我的mips-linux交叉编译器不支持C++11特性,所 ...

  5. SpringCloud Alibaba系列(三) Sentinel热点参数限流

    愿你生命中有够多的云翳,造就一个美好的黄昏 欢迎关注公众号[渣男小四],一个喜欢技术更喜欢艺术的青年 一.介绍 热点即经常访问的数据.很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据 ...

  6. CISCO交换机STP实验(生成树协议)

    目录 一.前言:生成树协议(STP) 二.CISCO交换机STP命令汇总 三.运用STP搭建简单拓扑 四.实战:STP综合实验 五.结语 一.前言:生成树协议(STP) 计算机网络中,我们为了减少网络 ...

  7. 037 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 04 switch结构

    037 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 04 switch结构 本文知识点:Java中的switch结构 选择结构分类 选择结构只有如下2种 ...

  8. plt.imshow()显示图片色差问题

    转载:https://www.cnblogs.com/darkknightzh/p/6039667.html 由于系统缺少某些库,导致cv2.imshow()无法使用,于是使用matplotlib.p ...

  9. C++ 异常处理 catch(...)介绍

    转载:https://blog.csdn.net/fcsfcsfcs/article/details/77717567 catch(-)能够捕获多种数据类型的异常对象,所以它提供给程序员一种对异常 对 ...

  10. shell-字符串及整数操作符讲解与多实践

    1. 字符串测试操作符 字符串测试操作符的作用:比较两个字符串是否相同.字符串长度是否为零,字符串是否为null(注:bash区分零长度字符串和空字符串)等. "="比较两个字符串 ...