多线程 -- sleep()方法和wait()方法区别

sleep()和wait()方法最大的区别就是:

1.

wait()方法会释放对象的锁,即在线程A wait期间,其他线程可以调用它的synchronized同步方法。

但是线程A sleep的时候,不会释放对象的锁。

其他的区别:

2.

Object类中的方法:wait() / notify() / notifyAll()

Thread类中的方法:sleep() / yield()

3.

wait()方法只能由持有对象锁的线程来调用(即wait()方法必须在同步块内执行),否则会抛出异常java.lang.IllegalMonitorStateException。

而sleep()方法任何线程都可以调用。


一, sleep()方法的使用


public class MyThread1 implements Runnable {
	static int a =0;

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyThread1 R = new MyThread1();
		Thread t1 = new Thread(R,"A");
		Thread t2 = new Thread(R,"B");
		t1.start();
		t2.start();
	}

	@Override
	public synchronized void run() {
		// TODO Auto-generated method stub
		for(int i=0;i<10;i++){
			a++;
			if(a==5){
				 try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}		
			}
			System.out.println(Thread.currentThread().getName()+"--> a = "+a);
			// this.notify();	
		}
		 
	}


}
打印出来的log:

A--> a = 1
A--> a = 2
A--> a = 3
A--> a = 4
A--> a = 5
A--> a = 6
A--> a = 7
A--> a = 8
A--> a = 9
A--> a = 10
B--> a = 11
B--> a = 12
B--> a = 13
B--> a = 14
B--> a = 15
B--> a = 16
B--> a = 17
B--> a = 18
B--> a = 19
B--> a = 20

由log可以看出,当a==5时,即使线程A通过sleep(1000)暂停了一秒,但线程B也不会开始执行,还是会等线程A执行完才执行。


二.将sleep()方法换成wait()方法


public class MyThread1 implements Runnable {
	static int a =0;

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyThread1 R = new MyThread1();
		Thread t1 = new Thread(R,"A");
		Thread t2 = new Thread(R,"B");
		t1.start();
		t2.start();
	}

	@Override
	public synchronized void run() {
		// TODO Auto-generated method stub
		for(int i=0;i<10;i++){
			a++;
			if(a==5){
				try {
					this.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			System.out.println(Thread.currentThread().getName()+"--> a = "+a);
			 this.notify();	
		}
		 
	}

}

打印出来的log:

A--> a = 1
A--> a = 2
A--> a = 3
A--> a = 4
B--> a = 6
B--> a = 7
B--> a = 8
B--> a = 9
B--> a = 10
B--> a = 11
B--> a = 12
B--> a = 13
B--> a = 14
B--> a = 15
A--> a = 15
A--> a = 16
A--> a = 17
A--> a = 18
A--> a = 19
A--> a = 20

由log可以看出,当a==5时,线程A wait(),此时线程A释放了对象R的锁,所以线程B可以开始执行,直到线程B执行结束后,线程A才接着上次的进度继续执行。所以有下面的log:

B--> a = 15
A--> a = 15

线程A调用wait()方法后,线程A将进入与对象R相关的等待池中(相当于处于阻塞状态),当线程B调用notify()方法后,将从与对象R相关的等待池中移走任意一个线程(在这里是移走线程A),此时线程A就一直等待(相当于处于就绪状态),直到获取对象R的锁(在这里是线程B执行完后,线程A获取对象R的锁),获取对象锁后,线程A从上一次中断的地方继续执行。

如果对象R相关的等待池中没有线程,那么notify()将不起作用。

notifyAll()的作用是移走与对象R相关的等待池中移走所有线程。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值