多线程中线程停止的问题

问题 

在学习多次线程的过程,使用中断标志来控制线程的停止,结果出现子线程不会中断一直在运行

package pageWeb;

public class ThreadDemo1 implements Runnable{
	public static void main(String[] args) throws InterruptedException {
		ThreadDemo1 t1 = new ThreadDemo1();
		Thread t = new Thread(t1, "thread1");
		t.start();
		Thread.currentThread().sleep(10);
		t1.cancel();
		System.out.println("检查线程的运行状态标志flag:"+t1.flag);
		System.out.println(t.getName()+" is interrupt: "+t.isInterrupted());
		 
	}
	boolean flag = true;
	int i=0;
	@Override
	public void run() {
		System.out.println("thread运行状态:"+flag);
		while(flag){
			i++;
		}
		System.out.println("输出结果:  i= "+i);
	}
	public void cancel(){
		flag = false;
	}
}

运行结果:


这是因为在java多线程模型中,有一个公共的对象存储区,但是每个对象都有自己的私有备份,当一个线程改变了状态,jvm并不能保证这个线程

改变过的变量即使更新功能公共对象存储区的状态,可能造成问题,建议使用同步方法来获取flag。

修改后的代码如下:

package pageWeb;

public class ThreadDemo1 implements Runnable{
	public static void main(String[] args) throws InterruptedException {
		ThreadDemo1 t1 = new ThreadDemo1();
		Thread t = new Thread(t1, "thread1");
		t.start();
		Thread.currentThread().sleep(10);
		t1.cancel();
		System.out.println("检查线程的运行状态标志flag:"+t1.flag);
		System.out.println(t.getName()+" is interrupt: "+t.isInterrupted());
		 
	}
	private  boolean flag = true;
	private int  i=0;
	
	@Override
	public void run() {
		System.out.println("thread运行状态:"+flag);
		while(getFlag()){
			incrCount();
		}
		System.out.println("输出结果:  i= "+i);
	}
	public synchronized boolean getFlag (){
		return flag;
	}
	private synchronized void incrCount(){
		i++;
	}
	public synchronized void cancel(){
		flag = false;
	}
}

说明:

还有一点,特别是涉及网络的多线程,如果发生了网络阻塞(在while循环里面发生),那么,即使flag状态比如改变成false,由于程序被阻塞,线程用这种方法是永远都不会被停止的。 
举个例子:比如上面的程序,如果code1是一段网络程式,如果在code1发生了阻塞,阻塞的意义就是得不到请求的 
资源,在无限期等待,这个时候,runflag状态的变化对while循环是起不了作用的,线程不会被停止。 
笔者曾经参与多个涉及到获取网络资源的java程式,经常遇到因为网络的阻塞引起的线程问题。 
如果你的程式可能涉及到网络阻塞,或者有可能发生某种消息接受的阻塞。那么,请不要用这种方法来停止线程。

2. 另一个解释:

典型的多线程Happens-before Order问题,参考java语言规范-Happens-before Order
针对这个demo而言,java1.5之后的规范推荐的解决方法是在共享属性前增加参数volatile  我也是一头雾水,先记着。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值