`
jgsj
  • 浏览: 963381 次
文章分类
社区版块
存档分类
最新评论

线程中不可避免的wait/notify/notifyAll/join

 
阅读更多

在运用线程的过程中,不可避免的要遇到wait()、notify()、notifyAll()、join()这几个方法,但是首先需要注意的是,这些方法的调用对象,前三个方法的调用对象都是object,而join方法是作为一个Thread对象的方法调用的。

Wait()和notify方法的使用,当线程A需要等待线程B完成了某些操作之后才能继续执行,此时线程A就可以调用obj.wait()将线程暂时进入等待状态,在线程B完成了某些操作之后再调用obj.nofity()方法,从而A得以继续执行,其中obJ是A和B都可见得任意的Object对象

例如下面的代码,第一个启动的线程,调用了obj.wait()方法,那么第一个启动的线程将进入等待状态,直到第二个线程调用了notify方法,那么前面进入等待的线程才会再次被启动。

public class Test1 {
	
	public static void main(String args []){
		
		 final Object obj = new Object();
		 final boolean finished = false;
		
		 new Thread(){
			public void run() {
				System.out.println("线程1启动了");
				synchronized(obj){
					
						try {
							System.out.println("线程1进入暂停状态");
							obj.wait(200000);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				
				System.out.println("线程1结束了");
			}
		}.start();
		
		
		new Thread(){
			public void run() {
				synchronized(obj){
					System.out.println("唤醒线程被启动了");
				//	finished =true;
				
						obj.notifyAll();
					
						System.out.println("线程1即将再次启动了");
					}
			
				}
			
		}.start();
		
	}
}
那么从上面的分析可以知道控制台输出的结果如下

在object方法中有notifyAll()方法和notify()方法,这两个方法的区别在于前者会唤醒前面所有进入等待状态的线程,第二个方法只会唤醒前面所有在等待状态线程中的第一个进入等待状态的线程。


wait()和notify方法多用线程之间某些资源的共享,而join方法多用线程之间联合完成某些任务。从下面的例子我们可以看出,当在主线程之中调用了线程threadone的join方法时,主线程会等待join方法参数指定的时间,在等待的时间内,主线程进入暂停状态,在等待的时间结束之后,主线程继续运行。例子中,还加入对线程threadone是否存活的判断,即当threadone还是存活状态的时候,主线程每次等待一秒钟,如果threadone线程死掉,那么主线程将不再等待。

package com.learnjava.jointest;

public class Jointest {

	public static void main(String args[]){
		Thread threadone = new Thread(){
			@Override
			public void run() {
				System.out.println("线程即将1启动");
				for(int i = 0 ;i < 10 ;i++){
					try {
						System.out.println("线程1正在运行"+i);
						this.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				System.out.println("线程1结束运行");
			}
		};
		threadone.start();
		
		
	
		
		
		while(threadone.isAlive()){
			try {
				threadone.join(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("等待线程1结束");
		}
		System.out.println("等待结束");
	}
	
	
	
}

通常对线程不可能永远的等下去,例如当需要等待的时间很长,我们又不想等待那么长的时间的时候,这就需要我们根据业务逻辑调用线程的interrupte方法,用于中断指定的线程。在下面的例子中,我们定了一个变量time.当time大于了我们的timeout的时候,threadone 将会被中断,

package com.learnjava.jointest;

public class Jointest {

	public static void main(String args[]){
		
		int timeout = 2000;
		int time = 0;
		
		
		Thread threadone = new Thread(){
			@Override
			public void run() {
				System.out.println("线程即将1启动");
				for(int i = 0 ;i < 1 ;i++){
					try {
					
						System.out.println("线程1正在运行"+i);
						this.sleep(10000000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				System.out.println("线程1结束运行");
			}
		};
		threadone.start();
		
		
	
		
		
		while(threadone.isAlive()&& time <= timeout){
			try {
				threadone.join(300);
				time += 300;
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("等待线程1结束");
		}
		
		if(time > timeout){
			threadone.interrupt();
		}
		System.out.println("等待结束");
	}
	
	
	
}


文章参考书籍:Android程序设计





分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics