一.Lock接口

常用方法

Lock提供了一个更加面对对象的锁,在该锁中提供了更多的操作锁的功能。

使用Lock接口,以及其中的lock()方法和unlock()方法替代同步,对电影院卖票案例中Ticket类进行如下代码修改:

public class Ticket implements Runnable {
//共100票
int ticket = 100; //创建Lock锁对象
Lock ck = new ReentrantLock(); @Override
public void run() {
//模拟卖票
while(true){
//synchronized (lock){
ck.lock();
if (ticket > 0) {
//模拟选坐的操作
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在卖票:" + ticket--);
}
ck.unlock();
//}
}
}
}

二.死锁

同步锁使用的弊端:当线程任务中出现了多个同步(多个锁)时,如果同步中嵌套了其他的同步。这时容易引发一种现象:程序出现无限等待,这种现象我们称为死锁。这种情况能避免就避免掉。

public class LockA {
private LockA(){}
public final static LockA locka=new LockA();
}
public class LockB {
private LockB(){}
public final static LockB lockb=new LockB();
}
//线程任务类
public class DeadLock implements Runnable{
private int i=0;
public void run() {
while(true){
if(i%2==0){
//先进A同步,再进B同步
synchronized(LockA.locka){
System.out.println("if....locka");
synchronized (LockB.lockb) {
System.out.println("if....lockb");
}
}
}else{
//先进B同步,再进A同步
synchronized(LockB.lockb){
System.out.println("else....lockb");
synchronized (LockA.locka) {
System.out.println("else....locka");
}
}
}
i++;
}
} }
//测试类
public class Demo01 {
public static void main(String[] args) {
DeadLock d1=new DeadLock();
Thread t0=new Thread(d1);
Thread t1=new Thread(d1);
t0.start();
t1.start();
}
}

 三.等待唤醒机制

线程之间的通信:多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同。通过一定的手段使各个线程能有效的利用资源。而这种手段即—— 等待唤醒机制。

等待唤醒机制所涉及到的方法:

①wait() :等待,将正在执行的线程释放其执行资格 和 执行权,并存储到线程池中。

②notify():唤醒,唤醒线程池中被wait()的线程,一次唤醒一个,而且是任意的。

③notifyAll(): 唤醒全部:可以将线程池中的所有wait() 线程都唤醒。

唤醒的意思就是让线程池中的线程具备执行资格。这些方法都是在同步中才有效。同时这些方法在使用时必须标明所属锁,这样才可以明确出这些方法操作的到底是哪个锁上的线程。

这些方法被定义在了Object类中,因为这些方法在使用时,必须要标明所属的锁,而锁又可以是任意对象。能被任意对象调用的方法一定定义在Object类中。

如上图说示,输入线程向Resource中输入name ,sex , 输出线程从资源中输出,先要完成的任务是:

1.当input发现Resource中没有数据时,开始输入,输入完成后,叫output来输出。如果发现有数据,就wait();

2.当output发现Resource中没有数据时,就wait() ;当发现有数据时,就输出,然后,叫醒input来输入数据。

//模拟资源类
public class Resource {
public String name;
public int age; public boolean flag; }
//Input类
public class Input implements Runnable{
//对resource进行赋值
private Resource r;
public Input(){}
public Input(Resource r){
this.r=r;
}
public void run() {
int i=0;
while(true){
synchronized (r) {
if(r.flag){
try {
r.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(i%2==0){
r.name="张三";
r.age=18;
}else{
r.name="lisi";
r.age=81;
}
r.flag=true;
r.notify();
}
i++;
}
}
}
//Output类
public class Output implements Runnable{
private Resource r;
public Output(){}
public Output(Resource r){
this.r=r;
}
public void run() {
//对resource输出
while(true){
synchronized (r) {
//判断标记
if(!r.flag){
try {
r.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(r.name+"..."+r.age);
r.flag = false;
r.notify();
}
}
} }
//测试类
public class Demo01 {
public static void main(String[] args) {
Resource r=new Resource();
Input in=new Input(r);
Output out=new Output(r);
Thread tin=new Thread(in);
Thread tout=new Thread(out);
tin.start();
tout.start();
}
}

java多线程(死锁,lock接口,等待唤醒机制)的更多相关文章

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

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

  2. Java多线程之三volatile与等待通知机制示例

    原子性,可见性与有序性 在多线程中,线程同步的时候一般需要考虑原子性,可见性与有序性 原子性 原子性定义:一个操作或者多个操作在执行过程中要么全部执行完成,要么全部都不执行,不存在执行一部分的情况. ...

  3. java 多线程:线程通信-等待通知机制wait和notify方法;(同步代码块synchronized和while循环相互嵌套的差异);管道通信:PipedInputStream;PipedOutputStream;PipedWriter; PipedReader

    1.等待通知机制: 等待通知机制的原理和厨师与服务员的关系很相似: 1,厨师做完一道菜的时间不确定,所以厨师将菜品放到"菜品传递台"上的时间不确定 2,服务员什么时候可以取到菜,必 ...

  4. Java多线程的~~~Lock接口和ReentrantLock使用

    在多线程开发.除了synchronized这个keyword外,我们还通过Lock接口来实现这样的效果.由Lock接口来实现 这样的多线程加锁效果的优点是非常的灵活,我们不在须要对整个函数加锁,并且能 ...

  5. Android-Java多线程通讯(生产者 消费者)&等待唤醒机制

    多线程通讯:例如:有一个线程任务在run生产,还有一个线程任务在run消费: VIP尊贵的身份,生产者 消费者 方式,(精心生产制作一个超级无敌好吃的面包,卖给VIP尊贵的身份消费者)生产与消费 一对 ...

  6. Android-Java多线程通讯(生产者 消费者)&10条线程对-等待唤醒/机制的管理

    上一篇博客 Android-Java多线程通讯(生产者 消费者)&等待唤醒机制 是两条线程(Thread-0 / Thread-1) 在被CPU随机切换执行: 而今天这篇博客是,在上一篇博客A ...

  7. 00103_死锁、Lock接口、等待唤醒机制

    1.死锁 (1)同步锁使用的弊端:当线程任务中出现了多个同步(多个锁)时,如果同步中嵌套了其他的同步.这时容易引发一种现象:程序出现无限等待,这种现象我们称为死锁.这种情况能避免就避免掉: synch ...

  8. java ->多线程_线程同步、死锁、等待唤醒机制

    线程安全 如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的. l  我们通过一个案例,演示线 ...

  9. JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制

    JAVA之旅(十四)--静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制 JAVA之旅,一路有你,加油! 一.静态同步函数的锁是clas ...

随机推荐

  1. 探索ASP.NET Core中的IStartupFilter

    原文:Exploring IStartupFilter in ASP.NET Core 作者:Andrew Lock 译者:Lamond Lu 在本篇博客中,我将介绍一下IStartupFilter, ...

  2. Android--SoundPool

    前言 在Android中播放音频文件经常会用到MediaPlayer,但是MediaPlayer存在一些不足的地方,如:资源占用量较高.加载延迟时间较长.不支持多个音频同时播放等.这些缺点决定了Med ...

  3. 把路由器改装成git服务器(OpenWRT环境的GIT服务器搭建)

    在单位中,通常都标配了git服务器用来管理代码. 对于家庭或者小办公室,这种方式有点不经济.当然如果是开源项目就简单了,刚刚被微软收购的github是理想选择.但如果没有打算开源,我今天的话题可能对你 ...

  4. Linux~yum命令安装程序

    当我们使用linux的最小安装时,很多系统程序都没有被安装,这时,我们可以通过yum命令安装指定的包包,当然前提是你的linux处于联网状态的,下面说一下yum的用法 1 显示程序列表(联网的) yu ...

  5. 痞子衡嵌入式:一表全搜罗常见低功耗广域物联网协议(NB-IoT/eMTC/LoRa/SigFox...)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是低功耗广域物联网协议. 上一篇痞子衡给大家搜罗了短距离无线通信协议,它是物联网的基础,但它的应用距离比较短,对于长距离的物联网应用鞭长莫 ...

  6. 痞子衡嵌入式:串口调试工具Jays-PyCOM诞生记(4)- 联合调试(vspd, sscom, PyCharm2018.2)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是串口调试工具Jays-PyCOM诞生之联合调试. 软件开发离不开调试,调试手段分两种:一是黑盒调试,即直接从输入/输出角度测试软件功能是 ...

  7. MyCat做MySQL负载均衡(享学课堂,咕泡学院听课笔记)

    不要用战术上的勤奋,掩盖战略上的懒惰. 一.数据库集群演示 演示的数据库的表分了三种, 1.配置表,存储一些配置文件,其他业务表需要关联读取,每个数据库都存储配置表的全部内容,即操作Mycat,所有集 ...

  8. js中按钮去触发定时器,那么多次点击这个定时器会越来越快,解决方法

    并不是越来越快, 而是越来越多;   $('button:first').click(function(){ // 记录ID var timerId = setInterval(function(){ ...

  9. arcgis api 3.x for js 入门开发系列四地图查询(附源码下载)

    前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 3.x for js:esri 官网 api,里面详细的介绍 arcgis api 3.x 各个类 ...

  10. Arcpy多线程热力图

        起因是这样一段对话,领导:你会用脚本生成热力图图片吗?我:可以研究下.领导:那这个需求就给你了.我:......     经过一番研究,研究出大概的思路,先将有经纬度的表中的数据筛选出表并生成 ...