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. CMake 常用命令

    cmake是现在主流的用于多平台C++构建系统,本文用来记录cmake的一些常用命令的索引,加上一些自己理解,理解有误的话,欢迎大家指出. 常用路径 CMAKE_SOURCE_DIR: 顶级cmake ...

  2. Java基础一篇过(一)反射

    一.反射是个啥 定义 : 在运行状态中动态获取的类的信息以及动态调用对象的方法,这种功能称为java语言的反射机制. 对于任意一个类,都能够知道这个类的所有属性和方法. 对于任意一个对象,都能够调用它 ...

  3. javaweb修改表单参数---使用过滤器

    需求: 所有的字段要将空字符串转成null: 问题: 我们知道表单如果不写值的时候,传递到后台的不是null,而且是空字符串.那么怎么改成null呢? 解决: 使用过滤器,将请求的参数修改过后继续,再 ...

  4. 使用jpa的注意事项

    @Transactional 事务注解 nativeQuery = true表示使用写的sql,不是HQL@Modifying 注解完成修改操作使用jap时,在实体类的类名上面加上 @Entity@T ...

  5. jpeg编解码概述

    本博文为概览性介绍.后面有空了再分几篇博文分别介绍所用到的技术细节. 1.编解码目标 编码和解码是个逆过程.jpeg编码的目的在于图形去冗余,进行数据压缩,解码的目的在于还原图像,使能够进行预览. 2 ...

  6. Java基础系列-Optional

    原创文章,转载请标注出处:https://www.cnblogs.com/V1haoge/p/10755368.html 一.概述 Optional的引入是为了解决null的问题,那么到底是解决nul ...

  7. 日志分析平台ELK之日志收集器filebeat

    前面我们了解了elk集群中的logstash的用法,使用logstash处理日志挺好的,但是有一个缺陷,就是太慢了:当然logstash慢的原因是它依赖jruby虚拟机,jruby虚拟机就是用java ...

  8. Linux 百度网盘卡在等待页

    解决办法1 如果无法登录百度网盘,一直在加载,运行命令:rm -rf ~/baidunetdisk 然后关闭百度客户端,重新登录百度客户端. 解决办法2 如果已经登录进百度网盘,退出百度网盘时,不要直 ...

  9. Java源码详解系列(十一)--Spring的使用和源码

    Spring 是一个一站式的 Java 框架,致力于提高我们项目开发的效率.通过 Spring,我们可以避免编写大量额外代码,更专注于我们的核心逻辑.目前,Spring 已经成为最受欢迎的 Java ...

  10. 多台centos7服务器实现SSH免密登陆

    一.环境 centos7.x 三台 node1.node2.node3 二.实现免密登陆 2.1.node1上,生成公钥与私钥 [root@node1 ~]# ssh-keygen Generatin ...