Java 多线程中的死锁问题,数据竞争所致?

海盗2019 2005-12-20 05:00:54
在某个多线程程序中,线程A对线程B进行监控,现公布大致的代码,请大家讨论2个问题:
1、监控线程一般都是怎么来维护、操作的?
2、程序中的这种监控会不会引起数据竞争?恶性的数据竞争?甚至引起死锁?

程序如下:
public class ThreadA extend Thread
{
public boolean conti = true;
public boolean dead = false;

public void run()
{
while ( conti )
{
dead = false;
// do something
sleep( 1000 );
}
}

public void exit()
{
conti = false;
}
}

public class ThreadB extend Thread
{
public boolean conti = true;
public ThreadA ta;

public ThreadB( ThreadA ta )
{
this.ta = ta;
}

public void run()
{
while ( conti )
{
if ( ta.dead )
{
ta.exit();
// restart ta
}
ta.dead = false;
sleep( 30000 );
}
}

public void exit()
{
conti = false;
}
}

参考:多线程Java程序中常见错误的巧处理
http://software.ccidnet.com/art/322/20030410/43222_1.html
...全文
407 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
海盗2019 2005-12-29
  • 打赏
  • 举报
回复
非常感谢crazycy的帮助,部分程序暂时使用了监控异常的方法,还在观察中.
crazycy 2005-12-24
  • 打赏
  • 举报
回复
我摘录的一段文章:
关于volatile
coffeecup 发表于 2004-08-31
我们知道,在Java中设置变量值的操作,除了long和double类型的变量外都是原子操作,也就是说,对于变量值的简单读写操作没有必要进行同步。这在JVM 1.2之前,Java的内存模型实现总是从主存读取变量,是不需要进行特别的注意的。而随着JVM的成熟和优化,现在在多线程环境下volatile关键字的使用变得非常重要。在当前的Java内存模型下,线程可以把变量保存在本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值的拷贝,造成数据的不一致。要解决这个问题,只需要像在本程序中的这样,把该变量声明为volatile(不稳定的)即可,这就指示JVM,这个变量是不稳定的,每次使用它都到主存中进行读取。一般说来,多任务环境下各任务间共享的标志都应该加volatile修饰。


crazycy 2005-12-24
  • 打赏
  • 举报
回复
楼主的程序对于dead,被多个线程同时使用,要么使用synchronized修饰方法或者代码块中的dead;要么使用volatile修饰dead变量
crazycy 2005-12-24
  • 打赏
  • 举报
回复
有一点就是java1.2之后的内存模型,其提到线程在执行过程中对变量存有一份本地的拷贝,不能及时让其他线程获得;
niko7 2005-12-23
  • 打赏
  • 举报
回复
关注
海盗2019 2005-12-23
  • 打赏
  • 举报
回复
考虑了下对线程的异常监控(测试的时候也许用的着):
1、主控程序TA,启动业务处理线程TB和TB的异常监控线程TC;
2、TB.exit(),捕获并处理相关的数据,设置开关为false;
3、监控线程TC通过TB.activeCount()减少和开关为true,获知TB有异常发生,设置TB的开关为false,停掉TB,新运行TB_1。

只可以监控固定线程数的程序发生异常,死锁问题麽有解决。:(
treeroot 2005-12-22
  • 打赏
  • 举报
回复
up
海盗2019 2005-12-22
  • 打赏
  • 举报
回复
谢谢yuzl和Jimmy。

2、测试程序中,存在数据反复回退,担忧。

以前习惯不给线程起名字,监控起来比较麻烦。
最近几天,程序又突然变得稳定起来,想找出2个引起死锁的线程还得慢慢等待。
TinyJimmy 2005-12-21
  • 打赏
  • 举报
回复
1、监控线程一般都是怎么来维护、操作的?
我采用Manager-Client方式去做. 管理线程叫Manager, 负责被控线程启动/停止/监控状态等维护.一个管理线程可管理多个子线程.

2、程序中的这种监控会不会引起数据竞争?恶性的数据竞争?甚至引起死锁?
因为每个线程有自己的CPU时间, 如果都读写同一个线程不安全的对象, 或调用可能锁的过程就可能死锁. 数据库的死锁就是很好的例子.
yuzl32 2005-12-20
  • 打赏
  • 举报
回复
1、监控线程一般是由一个独立线程来引导实现的.
2、可能会,这要看你怎么维护临界资源,如果没有临界资源的话,便不必担心这问题.

62,614

社区成员

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

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