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. MyBatis常用实现方式

    MyBatis 是一个优秀的基于 java 的持久层框架,它内部封装了 jdbc,使开发者只需要关注 sql 语句本身,而不需要花费精力去处理加载驱动.创建连接.创建 statement 等繁杂的过程 ...

  2. python的多种魔术方法

    目录 new str & repr iter getitem.setitem.delitem getattr.setattr.delattr call slots 定制类和魔法方法 new s ...

  3. vue学习08 v-bind指令

    目录 vue学习08 v-bind指令 v-bind指令的作用是为元素绑定属性 完整写法是v-bind:属性名,可简写为:属性名 练习代码为: 运行效果为: vue学习08 v-bind指令 v-bi ...

  4. CentOS 8 安装 VirtualBox 增强功能

    环境介绍 Machine: NUC8i5BEK OS: macOS Catalina 10.15.6 VirtualBox: 6.1.12 r139181 (Qt5.6.3) CentOS: 8.2. ...

  5. 基于SpringBoot+SpringDataJpa后台管理

    昨天朋友找我喝酒,说30岁了,比较焦虑,钱没赚到,整天被媳妇数落. 其实现在我们看到的不一定就事真实的情况,就算从高斯分布看,平平淡淡的人生才是大部分人的轨迹.当然抖音.知乎上的不能比,人均收入百万, ...

  6. --initialize specified but the data directory has files in it. Aborting

    出错版本: mysql 5.7 why? yum 安装数据库时候,默认数据存放目录为 /var/lib/mysql,然而这个目录下有数据 way? 进入 /var/lb/mysql 目录下清空该目录下 ...

  7. heap是堆,stack是栈

    1.栈是用来存放基本类型的变量和引用类型的变量,堆用来存放new出来的对象和数组. 2.栈的存取速度快,但不灵活.堆的存取速度慢,但是存取灵活,空间动态分配. 3.栈在建立在连续的物理位置上,而堆只需 ...

  8. 概率派VS贝叶斯派

    机器学习中的MLE和MAP两大学派的争论: 频率学派 - Frequentist - Maximum Likelihood Estimation (MLE,最大似然估计): 频率学派认为世界是确定的, ...

  9. 认证授权:IdentityServer4 - 数据持久化

    前言: 前面的文章中IdentityServer4 配置内容都存储到内存中,本篇文章开始把配置信息存储到数据库中:本篇文章继续基于github的代码来实现配置数据持久化到MySQL中 一.基于EFCo ...

  10. 【MySQL Errors】Table 'xxx' is marked as crashed and should be repaired 的解决方案

    现象描述 访问 Zabbix Web,出现如下错误提示: • Error in query [SELECT * FROM history_uint h WHERE h.itemid='25067' O ...