java中wait()、this.wait()、super.wait()、object.wait()的使用区别

今天有位同学过来问我下面代码中那个super.wait()是什么意思?

	public synchronized void waitAvailable() {
		try {
			if (num == "wait")
			    super.wait();
		} catch (InterruptedException ex) {
		}
	}


那我们今天就来讲一下synchronized关键字中条件对象的使用吧


(1) 线程持有当前对象的锁的结构

	public synchronized void waitAvailable() {

	}
	
	public void waitAvailable() {
		synchronized(this) {
			
		}
	}


我们知道wait()\notify()\notifyAll() 方法都是java.lang.Object类的 native方法,如果我们要在某个线程中的synchronized块中调用 wait()\notify()\notifyAll() 这几个方法,

有且只能调用线程所持有的那个锁的对象的wait()\notify()\notifyAll()方法。如果当前线程不是对象锁的持有者,则持有锁的方法就会抛出一个java.lang.IllegalMonitorStateException异常。


我们来看如下的代码实例:

public class Method {
	private int num = 10;
	
//	private Object lock = new Object();
	
	// 当前线程吃用当前对象的所
	public synchronized void method() {
	
		if (num > 8) {
			for (int i = 0; i<3 ;i++) {
				System.out.println(Thread.currentThread().getName() + " : " + num);
				num--;
			}
			try {
				System.out.println(Thread.currentThread().getName() + " wait begin ");
				//调用父类Object的native方法wait()
//				super.wait();
//			    this.wait();
     			wait();
				System.out.println(Thread.currentThread().getName() + " wait end ");
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} 
		
		if (num <=7 && num > 1) {
			for (int i = 0; i<7 ;i++) {
				System.out.println(Thread.currentThread().getName() + " : " + num);
				num--;
			}
			//调用父类Object的native方法wait()
//			super.notify();
//			this.notify();		
			notify();
			System.out.println(Thread.currentThread().getName() + " notify ");
		}	
	}
	
	public static void main(String [] args) {
		final Method m = new Method();
		Thread t1= new Thread(new Runnable() {
			public void run() {
				m.method();
			}
		},"A");
		
		Thread t2= new Thread(new Runnable() {
			public void run() {
				m.method();
			}
		},"B");
		t1.start();
		t2.start();
	}
}

java 中任何类都是从java.lang.Object类的子类,那么任何类就继承了java.lang.Object类的公有的wait()\notify()\notifyAll() 这几个native方法。

若线程持有的是当前对象的锁 那么直接调用wait()、super.wait()、this.wait(),都是直接调用的当前对象的方法。所以在此处代码中调用wait()\notify()、super.wait()\super.notify、this.wait()\this.notify是一样的。

(2) 线程持有显示锁的结构

	private Object lock = new Object();
	
	public void method () {
		synchronized(lock) {
			
		}
	}

我们直接上代码:

public class Method {
	private int num = 10;
	
	private Object lock = new Object();
	

	public synchronized void method() {
		// 当前线程持有对象lock的锁 那么下面应用条件对象时就必须调用锁的相应的方法
		synchronized(lock) {
			if (num > 8) {
				for (int i = 0; i<3 ;i++) {
					System.out.println(Thread.currentThread().getName() + " : " + num);
					num--;
				}
				try {
					System.out.println(Thread.currentThread().getName() + " wait begin ");
					//调用父类Object的native方法wait()
//				super.wait();
//			    this.wait();
//     			wait();
					// 调用显示锁lock的wait()方法
					lock.wait();
					System.out.println(Thread.currentThread().getName() + " wait end ");
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			} 
			
			if (num <=7 && num > 1) {
				for (int i = 0; i<7 ;i++) {
					System.out.println(Thread.currentThread().getName() + " : " + num);
					num--;
				}
				//调用父类Object的native方法wait()
//			super.notify();
//			this.notify();		
//			notify();
				// 调用显示锁lock的notify()方法
				lock.notify();
				System.out.println(Thread.currentThread().getName() + " notify ");
			}	
		}
	
	}
	
	public static void main(String [] args) {
		final Method m = new Method();
		Thread t1= new Thread(new Runnable() {
			public void run() {
				m.method();
			}
		},"A");
		
		Thread t2= new Thread(new Runnable() {
			public void run() {
				m.method();
			}
		},"B");
		t1.start();
		t2.start();
	}
}

上例中 我们让当前线程持有的是lock对象的锁,那么在使用条件对象时就必须调用当前锁lock对象的 wait()\notify()\notifyAll()方法。当然这些方法也是从java.lang.Object类继承而来。


如果当前线程持有的是对象A的锁,而使用条件对象时调用的是对象B的wait()\notify()方法组合,那么就会抛出一个java.lang.IllegalMonitorStateException异常


代码如下:

public class Method {
	private int num = 10;
	
	private Object lock = new Object();
	

	public synchronized void method() {
		// 当前线程持有当前对象this的锁
		synchronized(this) {
			if (num > 8) {
				for (int i = 0; i<3 ;i++) {
					System.out.println(Thread.currentThread().getName() + " : " + num);
					num--;
				}
				try {
					System.out.println(Thread.currentThread().getName() + " wait begin ");
					//调用父类Object的native方法wait()
//				super.wait();
//			    this.wait();
//     			wait();
					// 使用条件对象时 调用显示锁lock的wait()方法  这样就会抛出异常
					lock.wait();
					System.out.println(Thread.currentThread().getName() + " wait end ");
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			} 
			
			if (num <=7 && num > 1) {
				for (int i = 0; i<7 ;i++) {
					System.out.println(Thread.currentThread().getName() + " : " + num);
					num--;
				}
				//调用父类Object的native方法wait()
//			super.notify();
//			this.notify();		
//			notify();
				// 使用条件对象时 调用显示锁lock的notify()方法  这样就会抛出异常
				lock.notify();
				System.out.println(Thread.currentThread().getName() + " notify ");
			}	
		}
	
	}
	
	public static void main(String [] args) {
		final Method m = new Method();
		Thread t1= new Thread(new Runnable() {
			public void run() {
				m.method();
			}
		},"A");
		
		Thread t2= new Thread(new Runnable() {
			public void run() {
				m.method();
			}
		},"B");
		t1.start();
		t2.start();
	}
}

输出结果:
A : 10
A : 9
A : 8
A wait begin 
B : 7
B : 6
B : 5
B : 4
B : 3
B : 2
B : 1
Exception in thread "A" java.lang.IllegalMonitorStateException
	at java.lang.Object.wait(Native Method)
	at java.lang.Object.wait(Object.java:485)
	at com.renren.testwait.Method.method(Method.java:24)
	at com.renren.testwait.Method$1.run(Method.java:53)
	at java.lang.Thread.run(Thread.java:662)
Exception in thread "B" java.lang.IllegalMonitorStateException
	at java.lang.Object.notify(Native Method)
	at com.renren.testwait.Method.method(Method.java:42)
	at com.renren.testwait.Method$2.run(Method.java:59)
	at java.lang.Thread.run(Thread.java:662)










你可能感兴趣的:(java并发编程)