在某个多线程程序中,线程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

解决方案 »

  1.   

    1、监控线程一般都是怎么来维护、操作的?
       我采用Manager-Client方式去做. 管理线程叫Manager, 负责被控线程启动/停止/监控状态等维护.一个管理线程可管理多个子线程.2、程序中的这种监控会不会引起数据竞争?恶性的数据竞争?甚至引起死锁?
       因为每个线程有自己的CPU时间, 如果都读写同一个线程不安全的对象, 或调用可能锁的过程就可能死锁. 数据库的死锁就是很好的例子.
      

  2.   

    谢谢yuzl和Jimmy。2、测试程序中,存在数据反复回退,担忧。以前习惯不给线程起名字,监控起来比较麻烦。
    最近几天,程序又突然变得稳定起来,想找出2个引起死锁的线程还得慢慢等待。
      

  3.   

    考虑了下对线程的异常监控(测试的时候也许用的着):
    1、主控程序TA,启动业务处理线程TB和TB的异常监控线程TC;
    2、TB.exit(),捕获并处理相关的数据,设置开关为false;
    3、监控线程TC通过TB.activeCount()减少和开关为true,获知TB有异常发生,设置TB的开关为false,停掉TB,新运行TB_1。只可以监控固定线程数的程序发生异常,死锁问题麽有解决。:(
      

  4.   

    有一点就是java1.2之后的内存模型,其提到线程在执行过程中对变量存有一份本地的拷贝,不能及时让其他线程获得;
      

  5.   

    楼主的程序对于dead,被多个线程同时使用,要么使用synchronized修饰方法或者代码块中的dead;要么使用volatile修饰dead变量
      

  6.   

    我摘录的一段文章:
    关于volatile 
    coffeecup 发表于 2004-08-31 
    我们知道,在Java中设置变量值的操作,除了long和double类型的变量外都是原子操作,也就是说,对于变量值的简单读写操作没有必要进行同步。这在JVM 1.2之前,Java的内存模型实现总是从主存读取变量,是不需要进行特别的注意的。而随着JVM的成熟和优化,现在在多线程环境下volatile关键字的使用变得非常重要。在当前的Java内存模型下,线程可以把变量保存在本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值的拷贝,造成数据的不一致。要解决这个问题,只需要像在本程序中的这样,把该变量声明为volatile(不稳定的)即可,这就指示JVM,这个变量是不稳定的,每次使用它都到主存中进行读取。一般说来,多任务环境下各任务间共享的标志都应该加volatile修饰。 
      

  7.   

    非常感谢crazycy的帮助,部分程序暂时使用了监控异常的方法,还在观察中.