java 多线程死锁机制

编程入门 行业动态 更新时间:2024-10-24 10:14:22

java 多线程<a href=https://www.elefans.com/category/jswz/34/1769948.html style=死锁机制"/>

java 多线程死锁机制

一.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 多线程死锁机制

本文发布于:2024-03-08 18:35:30,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1721843.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:死锁   多线程   机制   java

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!