线程死锁。请前辈帮忙看一下。

让生命去等候 2018-12-27 11:09:28
/**
多线程间通讯实例
*/
class Resource
{
private String name;
private String sex;
private boolean flag = false;

public synchronized void set(String name, String sex)
{
if (flag == true)
{
try
{
this.wait();
}
catch(InterruptedException e)
{
}
}
this.name = name;
this.sex = sex;
flag = true;
this.notify();
}

public synchronized void out()
{
if (flag != true)
{
try
{
this.wait();
}
catch (InterruptedException e)
{
}

System.out.println(name+"..+.."+sex);

flag = false;
notify();
}
}
}

//=======================================
class Input implements Runnable
{
Resource r;

Input(Resource r)
{
this.r = r;
}

public void run()
{
int x = 0;
while(true)
{

if (x == 0)
{
r.set("Mike", "Male");
}
else
{
r.set("丽丽", "女女女女");
}

x =(x + 1) % 2;
}
}
}
//============================================
class Output implements Runnable
{
Resource r;
Output(Resource r)
{
this.r = r;
}

public void run()
{
while(true)
{
r.out();
}

}
}
//=======================================
class ResourceDemo
{
public static void main(String[] args)
{
Resource r = new Resource();

Input in = new Input(r);
Output out = new Output(r);

Thread t1 = new Thread(in);
Thread t2 = new Thread(out);

t1.start();
t2.start();
}
}

我不知道哪里出了问题,形成了死锁。请高手帮忙指点一下。谢谢。
...全文
259 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
rumlee 2019-01-01
  • 打赏
  • 举报
回复
都确定了发生了死锁了,那还不简单吗,在发生死锁的时候,把所有的线程栈打出来看一下就一目了然了。
qq_39936465 2018-12-27
  • 打赏
  • 举报
回复
因为你程序虽然只有2个线程,但是其实是2个不同的线程,notify只能随机唤醒一个线程。你遇到的问题是jvm认为其中一个线程的优先度高于另一个线程,造成notify唤醒只能反复唤醒其中一个线程形成了死锁,建议用2个以上不同的线程时要用notifyAll()。
十八道胡同 2018-12-27
  • 打赏
  • 举报
回复

package com.demo;

/**
多线程间通讯实例
*/
class Resource
{
private String name;
private String sex;
private boolean flag = false;

public synchronized void set(String name, String sex)
{
if (flag == true)
{
try
{
this.wait();
}
catch(InterruptedException e)
{
}
}
this.name = name;
this.sex = sex;
flag = true;
this.notify();
}

public synchronized void out()
{
if (flag != true)
{
try
{
this.wait();
}
catch (InterruptedException e)
{
}

System.out.println(name+"..+.."+sex);

flag = false;
notify();
}
}
}

//=======================================
class Input implements Runnable
{
Resource r;

Input(Resource r)
{
this.r = r;
}

public void run()
{
int x = 0;
while(true)
{
System.out.println("in");
if (x == 0)
{
r.set("Mike", "Male");
}
else
{
r.set("丽丽", "女女女女");
}

x =(x + 1) % 2;
}
}
}
//============================================
class Output implements Runnable
{
Resource r;
Output(Resource r)
{
this.r = r;
}

public void run()
{
while(true)
{
System.out.println("out");
r.out();
}

}
}

class ResourceDemo
{
public static void main(String[] args)
{
Resource r = new Resource();

Input in = new Input(r);
Output out = new Output(r);

Thread t1 = new Thread(in);
Thread t2 = new Thread(out);

t1.start();
t2.start();
}
}



你看输出,代码是没有死锁的
qq_39936465 2018-12-27
  • 打赏
  • 举报
回复
引用 楼主 让生命去等候 的回复:
/** 多线程间通讯实例 */ class Resource { private String name; private String sex; private boolean flag = false; public synchronized void set(String name, String sex) { if (flag == true) { try { this.wait(); } catch(InterruptedException e) { } } this.name = name; this.sex = sex; flag = true; this.notify(); } public synchronized void out() { if (flag != true) { try { this.wait(); } catch (InterruptedException e) { } System.out.println(name+"..+.."+sex); flag = false; notify(); } } } //======================================= class Input implements Runnable { Resource r; Input(Resource r) { this.r = r; } public void run() { int x = 0; while(true) { if (x == 0) { r.set("Mike", "Male"); } else { r.set("丽丽", "女女女女"); } x =(x + 1) % 2; } } } //============================================ class Output implements Runnable { Resource r; Output(Resource r) { this.r = r; } public void run() { while(true) { r.out(); } } } //======================================= class ResourceDemo { public static void main(String[] args) { Resource r = new Resource(); Input in = new Input(r); Output out = new Output(r); Thread t1 = new Thread(in); Thread t2 = new Thread(out); t1.start(); t2.start(); } } 我不知道哪里出了问题,形成了死锁。请高手帮忙指点一下。谢谢。
你同步时用了 if来判断 用notify唤醒后 不会再次判断 flag标志位,程序会继续执行下去,这里的if要换成while,每次唤醒必须进行判断
柴田淳丿星 2018-12-27
  • 打赏
  • 举报
回复
把while改成if就可以看到效果
柴田淳丿星 2018-12-27
  • 打赏
  • 举报
回复
因为notify方法是在执行完同步代码之后通知在阻塞队列中的线程,也就是说notify的那个线程并不是立即释放锁,而是在同步方法执行完,释放锁以后,wait方法的那个线程才会继续执行。而你那个方法里死循环,就没法释放锁了
ToughPZG 2018-12-27
  • 打赏
  • 举报
回复
哦看错 了。。。
ToughPZG 2018-12-27
  • 打赏
  • 举报
回复
你这两个线程用的不是一个锁。
同步方法,是用当前对象作为锁,也就是用当前Resource 对象作为锁。而你没个线程里都有一个Resource对象,这是两个不同的对象(换在这里是有两把锁),他们各自调set()或者out()方法时,是把自己作为锁。而notify()方法只能唤醒使用相同锁的线程。所以你这个案例肯定会死锁。
十八道胡同 2018-12-27
  • 打赏
  • 举报
回复
qq_39936465 2018-12-27
  • 打赏
  • 举报
回复
notify虽然有随机性,但是到jvm中还有可能产生优先差异,所以notify用的时候要小心。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧