java 多线程 wait() 以及 notirfy() 简析--更正

之前转载的java 多线程 wait() 以及 notirfy() 简析一文,作者关于多线程wait()的论述是对的,但程序有些bug

package com.szn.multithread;

public class ThreadA {
	public static void main(String[] args) {
		ThreadB b = new ThreadB();
		b.start();
		System.out.println("b is start....");
		synchronized (b)// 括号里的b是什么意思,起什么作用?
		{
			try {
				System.out.println("Waiting for b to complete...");
				b.wait();// 这一句是什么意思,究竟让谁wait?
				System.out.println("Completed.Now back to main thread");
			} catch (InterruptedException e) {
			}
		}
		System.out.println("Total is :" + b.total);
	}
}

class ThreadB extends Thread {
	int total;

	public void run() {
		synchronized (this) {
			System.out.println("ThreadB is running..");
			for (int i = 0; i < 100; i++) {
				total += i;
			}

			System.out.println("in b, total is " + total);
			notify();
		}
	}
}

运行后结果和分析如下:

//结果1:

//b is start....
//Waiting for b to complete...
//ThreadB is running..
//in b, total is -2014260032
//Completed.Now back to main thread
//Total is :-2014260032
//问题1:
//根据结果显示,A线程中先进入了同步块,A线程获取了B线程对象的锁,
//那么B线程中,B线程应该不能再获取B线程对象的锁了,就不能执行同步块中的内容
//这样,A线程会执行到b.wait() 形成死锁
//解答:
//"wait()允许我们将线程置入“睡眠”状态,同时又“积极”地等待条件发生改变.
//而且只有在一个notify()或notifyAll()发生变化的时候,线程才会被唤醒,并检查条件是否有变.
//wait()却可以,它可以让同步方法或者同步块暂时放弃对象锁,
//而将它暂时让给其它需要对象锁的人(这里应该是程序块,或线程)用,
//这意味着可在执行wait()期间调用线程对象中的其他同步方法
//如果A线程先进入同步块,只能是A线程执行到wait(),B线程的同步块才有可能被执行

//结果2:
//b is start....
//ThreadB is running..
//in b, total is 4950
//Waiting for b to complete...
//问题2:
//这种情况下,b线程先执行了同步块,获取了对象锁
//这样A线程就必须等待B线程执行完毕(释放了对象锁)
//才能获取对象锁,执行同步块,由于b.wait()使得A线程进入阻塞状态,
//而B线程的notify()已经执行过了,A线程就进入死锁状态

如果想让程序正确执行,应该保证A线程先获取对象锁,这只需让B线程延时一下

更改后程序:

package com.szn.multithread;

public class ThreadA {
	public static void main(String[] args) {
		ThreadB b = new ThreadB();
		b.start();
		System.out.println("b is start....");
		synchronized (b)// 括号里的b是什么意思,起什么作用?
		{
			try {
				System.out.println("Waiting for b to complete...");
				b.wait();// 这一句是什么意思,究竟让谁wait?
				System.out.println("Completed.Now back to main thread");
			} catch (InterruptedException e) {
			}
		}
		System.out.println("Total is :" + b.total);
	}
}

class ThreadB extends Thread {
	int total;

	public void run() {
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		synchronized (this) {
			System.out.println("ThreadB is running..");
			for (int i = 0; i < 100; i++) {
				total += i;
			}

			System.out.println("in b, total is " + total);
			notify();
		}
	}
}


你可能感兴趣的:(java,多线程)