关于JAVA线程停止的思考

 一个好的软件线程通常都是可控制的,开发者不但可以利用多线程来提升软件的效率,以可以HOLD住线程,可以销毁线程,防止线程泄漏。

什么是JAVA的线程停止?

       前段时间,我还自认为线程的停止,指的是线程的销毁。如果我停止一个线程,那么这个线程将会被销毁,至于如何销毁,那都是JVM应该考虑的事情,我只需调用对应 的API(比如Thread.interrupt(), Thread.stop(), Thread.destroy())。

       后来发现不是那么一回事,JAVA中线程的停止是交给开发者来维护的,不是简简单单的调用了一个接口,线程就不复存在了,且线程所用的资源也都被释放了,如果真是这样,那JVM也真是太强大了。

       好的线程停止,是通过响应中断方法来实现的。

那么问题来了,谁有资格去停止线程?      

       线程的创建者(或者任务的提交者)应该负责来停止线程。当业务上需要中断一批任务时,把消息发送给线程的创建者或者任务的提交者(根据信息专家模式),因为他们持有线程的信息。

       一个好的线程写法,应该是提交和任务相分离。如果代码中出现这样的语句:

new Thread(Runnable).start()

       这是一个糟糕的写法,因为这意味着,创建的线程永远无法被人工的终止,当大量创建这样的线程时,这些线程就相当于无政府主义者,不受约束,一旦产生,将会自生自灭。而且这样 的线程不容易修改,假如工程中有一百个上述代码片段,现在任务要变成同步执行(原先的写法肯定是并发执行),如何?这样改动可能要该100处,这对于维护者或者重构者来说简直就是灾难。

       好的写法应该是任务的提交和创建相分离(上面是典型的创建和提交混合在一起了)。

       比如如下代码:

public class MyThreadSubmitter implements Executor {

	@Override
	public void execute(Runnable command) {
		Thread thread = new Thread(command);
		thread.start();
	}

}

       当想同步执行时,换一个方式就可以了,只需要改动一处,代码如下:

public class MyThreadSubmitter implements Executor {

	@Override
	public void execute(Runnable command) {
		command.run();
	}

}

       上面阐述了任务的提交和创建相分离,回归老问题:如何终止一个线程?上面已经简要回答了下:即由程序员来维护线程,在程序员写代码的时候,就要考虑到线程终止,通过响应线程中断信号来实现。而不是交由JVM,任凭JVM来销毁,这样是不符合业务逻辑的。

       那么如何来编写响应中断式的线程?这个用一个例子来说明。

public class Task implements Runnable {

	@Override
	public void run() {
		try {
			boolean isInterrupt = false;
			while (!(isInterrupt = Thread.interrupted())) {
				//处理业务逻辑
			}
			if (isInterrupt) {//相应线程中断
				
			}
		} catch (Throwable e) {//防止线程泄漏
			e.printStackTrace();
		} finally{
			//释放资源
		}
	}

}
      如何提交呢?
 
public class TaskSubmiter {
	private static ExecutorService executor = Executors.newCachedThreadPool();
	private List<Future<?>> futures = new ArrayList<Future<?>>();
	
	public void sumbit(Task task){
		futures.add(executor.submit(task));
	}
	
	public void stop(){
		for (int i = 0; i < futures.size(); i++) {
			Future<?> future = futures.get(i);
			if (!future.isCancelled()) {
				future.cancel(true);
			}
		}
		futures.clear();
	}
	
}

       因为TaskSubmiter是任务的提交者,故TaskSubmiter持有线程的上线文信息,发送停止指令,应发送到该类。stop接口提现了线程的停止。以上就是一个通过响应中断来实现线程停止的简单模型。

      


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值