线程常见方法2

wait()方法

其实wait()方法就是使线程停止运行。

1.方法wait()的作用是使当前执行代码的线程进行等待,它是Object类的方法,该方法是用来将当前线程置入“预执行队列”当中,并且在wait() 所处代码处停止执行,直到接到通知或被中断为止。

2.wait()方法只能在同步方法中或同步块中调用。如果调用wait()时,没有持有适当的锁,会抛出异常。

3.wait()方法执行后当前线程释放锁,线程与其他线程竞争重新获取锁

public class Line{
	public static void main(String[] args) throws InterruptedException {
		Object object=new Object();
		synchronized (object) {
			System.out.println("线程等待中,,,,,,,,,");
			
				object.wait();
			
		}
		System.out.println("线程等待结束");
	}
}

 结果:

线程等待中,,,,,,,,,

程序就在一直等待着,直到用另一个方法唤醒notify()。

notify()方法

notify方法就是使停止的线程继续执行。

1.它也要在同步方法或同步代码块中调用,该方法是用来通知那些可能等待该对象的对象锁的其他线程,对其发出通知notify,并使它们重新获取该对象的对象锁。如果有多个线程等待,则有线程规划器随机挑选出一个呈wait状态的线程。

2.在notify()方法后,当前线程不会马上释放对象锁,要等到执行notify()方法的线程将程序执行完,也就是退出同步代码块之后才会释放对象锁。

class MyThread implements Runnable{
	
	private boolean flag;
	private Object obj;
	
	
	public MyThread(boolean flag, Object obj) {
		super();
		this.flag = flag;
		this.obj = obj;
	}


	public void waitMethod() {
		synchronized (obj) {
			
				try {
					while(true) {
						System.out.println("wait()方法开始。。"+Thread.currentThread().getName());
					obj.wait();
					System.out.println("wait()方法结束。。"+Thread.currentThread().getName());
					}
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
		}
	}
	public void notifyMethod() {
		synchronized (obj) {
			
				try {
					
						System.out.println("notify()方法开始。。"+Thread.currentThread().getName());
					obj.notify();
					System.out.println("notify()方法结束。。"+Thread.currentThread().getName());
					
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
	}
	}

	public void run() {
		if(flag) {
			this.waitMethod();
		}else {
			this.notifyMethod();
		}
	}
}

public class Line{
	public static void main(String[] args) throws InterruptedException {
		Object object=new Object();
		
		MyThread waitThread=new MyThread(true,object);
		MyThread notifyThread=new MyThread(false,object);
		Thread thread1=new Thread(waitThread,"wait线程");
		Thread thread2=new Thread(notifyThread,"notify线程");
		thread1.start();
		Thread.sleep(1000);
		thread2.start();
		System.out.println("main方法结束");
	}
}

结果:

wait()方法开始。。wait线程
main方法结束
notify()方法开始。。notify线程
notify()方法结束。。notify线程
wait()方法结束。。wait线程
wait()方法开始。。wait线程

notifyAl()方法

可以一次性唤醒所有等待线程。

class MyThread implements Runnable{
	
	private boolean flag;
	private Object obj;
	
	
	public MyThread(boolean flag, Object obj) {
		super();
		this.flag = flag;
		this.obj = obj;
	}


	public void waitMethod() {
		synchronized (obj) {
			
				try {
					while(true) {
						System.out.println("wait()方法开始。。"+Thread.currentThread().getName());
					obj.wait();
					System.out.println("wait()方法结束。。"+Thread.currentThread().getName());
					}
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
		}
	}
	public void notifyAllMethod() {
		synchronized (obj) {
			
				try {
					
						System.out.println("notifyAll()方法开始。。"+Thread.currentThread().getName());
					obj.notify();
					System.out.println("notifyAll()方法结束。。"+Thread.currentThread().getName());
					
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
	}
	}

	public void run() {
		if(flag) {
			this.waitMethod();
		}else {
			this.notifyAllMethod();
		}
	}
}

public class Line{
	public static void main(String[] args) throws InterruptedException {
		Object object=new Object();
		
		MyThread waitThread1=new MyThread(true,object);
		MyThread waitThread2=new MyThread(true,object);
		MyThread waitThread3=new MyThread(true,object);
		MyThread notifyAllThread=new MyThread(false,object);
		Thread thread1=new Thread(waitThread1,"wait线程1");
		Thread thread2=new Thread(waitThread2,"wait线程2");
		Thread thread3=new Thread(waitThread3,"wait线程3");
		Thread thread4=new Thread(notifyAllThread,"notify线程");
		thread1.start();
		thread2.start();
		thread3.start();
		Thread.sleep(1000);
		thread4.start();
		System.out.println("main方法结束");
	}
}

结果:

wait()方法开始。。wait线程1
wait()方法开始。。wait线程3
wait()方法开始。。wait线程2
main方法结束
notifyAll()方法开始。。notify线程
notifyAll()方法结束。。notify线程
wait()方法结束。。wait线程1
wait()方法开始。。wait线程1

注意:唤醒线程不能过早,如果在还没有线程在等待中,过早地唤醒线程,这个时候就会出现先唤醒再等待的效果了。

小结:出现阻塞的情况大体分为如下5种:

1.线程调用sleep方法,主动放弃占用的处理的资源处理器资源。

2.线程调用了阻塞式IO方法,在改方法返回前,该线程被阻塞。

3.线程视图获得一个同步监视器,但是该同步监视器正被其他线程锁持有。

4.线程等待某个通知。

5.程序调用了suspend方法将该线程挂起。此方法容易导致死锁,尽量避免使用该方法。

run()方法运行结束后进入销毁阶段,整个线程执行完毕。

每个所对象都有两个队列,一个是就绪队列,一个是阻塞队列。就绪队列存储了将要获得锁的线程,阻塞队列存储了被阻塞的线程。一个线程被唤醒后,才会进入就绪队列,等待CPU的跳读;反之,一个线程被wait()后,就会进入阻塞队列,等待下一次被唤醒。

猜你喜欢

转载自blog.csdn.net/xjy22/article/details/81624703