现在的位置: 首页 > 综合 > 正文

Java无限执行的线程启动与终止

2019年10月16日 ⁄ 综合 ⁄ 共 1391字 ⁄ 字号 评论关闭

需要开启一个线程,这个线程一直阻塞等待某件事情发生,最后主线程退出时将这个线程终止。

线程是这样的:

public class WatcherThread implements Runnable{
	private boolean dead = false;
	@Override
	public void run() {
	 	try {
            		synchronized (this) {
                		while (!dead) {
                    			wait();
                	}
                
                	System.out.println("线程退出");
            	}
        	} catch (InterruptedException e) 
        	{
        		e.printStackTrace();
        	}					
	}	
	//...其他代码
	

	/**
	 * 关闭当前监视者线程
	 */
	public void close()
	{
		this.dead = true;
		synchronized (this) {
			//注意,notify必须放在同步代码块中,与wait配合使用
			notify();
		}
		
	}
}

主线程创建这个线程:

watcher = new WatcherThread();
			
//开启线程,等待接收Zookeeper数据变化			
executor = Executors.newCachedThreadPool();
executor.execute(watcher);	

主线程终止这个线程:

watcher.close();
		
if(executor != null)
{
	executor.shutdown();
}

有几点需要注意:

(1)wait与notify/notifyAll

wait会一直阻塞在某一个对象之上,之后某个线程在该对象上调用notify/notifyAll方法,才会使得wait的线程回到就绪状态,但是不一定立即执行。

waitnotifynotifyAll这些方法是Object类的一部分,而不是Thread的一部分,所以可以把他们放进任何同步控制方法中。

实际上,只能在同步控制方法/同步控制块中调用wait,notify,notifyAll这几个方法,如果在非同步控制方法里面调用了这几个方法,可以编译通过,但是运行的时候会获得IllegalMonitorStateException异常。

注意:一般来说,waitnotify放在synchronozed(object)同步块中,并由这个object来调用。如果是synchronized(this),那么就直接调用。

(2)shutdown与shutdownNow

当线程池调用shutdown时,线程池的状态则立刻变成SHUTDOWN状态。此时,则不能再往线程池中添加任何任务,否则将会抛出RejectedExecutionException异常。但是,此时线程池不会立刻退出,直到添加到线程池中的任务都已经处理完成,才会退出。 

执行 shutdownNow() 方法,线程池的状态立刻变成STOP状态,并试图停止所有正在执行的线程,不再处理还在池队列中等待的任务,当然,它会返回那些未执行的任务。 
     它试图终止线程的方法是通过调用Thread.interrupt()方法来实现的,但是大家知道,这种方法的作用有限,如果线程中没有sleep 、wait、Condition、定时锁等应用, interrupt()方法是无法中断当前的线程的。所以,ShutdownNow()并不代表线程池就一定立即就能退出,它可能必须要等待所有正在执行的任务都执行完成了才能退出。 

抱歉!评论已关闭.