一、线程如何停止

使用stop()不安全。它会解除由线程获取的所有锁定,而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在。suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时其他任何线程都不能访问锁定的资源,除非被"挂起"的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。所以不应该使用suspend()。正确的做法是而应在自己的Thread类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程。jdk1.5后提供了condition对象,这个对象的await()和singal()方法也可以达到线程通信的效果。


二、wait和notify实例

子线程循环10次,主线程循环100次。接着子线程循环10次,主线程循环100次。如此循环50次。摘自张孝祥老师线程视频源码。

public class TraditionalThreadCommunication

{

public static void main(String[] args)

{

final Business business = new Business();

new Thread(new Runnable() {

public void run()

{

for (int i = 1; i <= 50; i++)

{

business.sub(i);

}

}

}).start();

for (int i = 1; i <= 50; i++)

{

business.main(i);

}

}

}

class Business

{

private boolean bShouldSub = true;

public synchronized void sub(int i)

{

while (!bShouldSub)

{

try

{

this.wait();

}

catch (InterruptedException e)

{

e.printStackTrace();

}

}

for (int j = 1; j <= 10; j++)

{

System.out.println("sub thread sequence of " + j + ",loop of " + i);

}

bShouldSub = false;

this.notify();

}


public synchronized void main(int i)

{

while (bShouldSub)

{

try

{

this.wait();

}

catch (InterruptedException e)

{

e.printStackTrace();

}

}

for (int j = 1; j <= 100; j++)

{

System.out.println("main thread sequence of " + j + ",loop of " + i);

}

bShouldSub = true;

this.notify();

}

}


三、Condition实例

public class Condition1Test

{

public static void main(String[] args)

{

final BusinessLock business = new BusinessLock();

new Thread(new Runnable() {

public void run()

{

for (int i = 1; i <= 50; i++)

{

business.sub(i);

}

}

}).start();

for (int i = 1; i <= 50; i++)

{

business.main(i);

}

}

}

class BusinessLock

{

private boolean bShouldSub = true;

ReentrantLock lock = new ReentrantLock();

Condition condition = lock.newCondition();


public void sub(int i)

{

lock.lock();

try

{

while (!bShouldSub)

{

try

{

condition.await();

}

catch (InterruptedException e)

{

e.printStackTrace();

}

}

for (int j = 1; j <= 10; j++)

{

System.out.println("sub thread sequence of " + j + ",loop of " + i);

}

bShouldSub = false;

condition.signal();

}

finally

{

lock.unlock();

}

}


public void main(int i)

{

lock.lock();

try

{

while (bShouldSub)

{

try

{

condition.await();

}

catch (InterruptedException e)

{

e.printStackTrace();

}

}

for (int j = 1; j <= 100; j++)

{

System.out.println("main thread sequence of " + j + ",loop of " + i);

}

bShouldSub = true;

condition.signal();

}

finally

{

lock.unlock();

}

}

}


四、Condition实例扩展

三个线程相互通信,main循环100次,sub2循环10次,sub3循环10次。接着main循环100次,sub2循环10次,sub3循环10次。如此循环50次。

public class Condition2Test

{

public static void main(String[] args)

{

final BusinessLock2 business = new BusinessLock2();

new Thread(new Runnable() {

public void run()

{

for (int i = 1; i <= 50; i++)

{

business.main(i);

}

}

}).start();


new Thread(new Runnable() {

public void run()

{

for (int i = 1; i <= 50; i++)

{

business.sub2(i);

}

}

}).start();


new Thread(new Runnable() {

public void run()

{

for (int i = 1; i <= 50; i++)

{

business.sub3(i);

}

}

}).start();

}

}


class BusinessLock2

{

private int bShouldSub = 1;

ReentrantLock lock = new ReentrantLock();

Condition condition1 = lock.newCondition();

Condition condition2 = lock.newCondition();

Condition condition3 = lock.newCondition();


public void main(int i)

{

lock.lock();

try

{

while (bShouldSub != 1)

{

try

{

condition1.await();

}

catch (InterruptedException e)

{

e.printStackTrace();

}

}

for (int j = 1; j <= 100; j++)

{

System.out.println("main thread sequence of " + j + ",loop of " + i);

}

bShouldSub = 2;

condition2.signal();

}

finally

{

lock.unlock();

}

}


public void sub2(int i)

{

lock.lock();

try

{

while (bShouldSub != 2)

{

try

{

condition2.await();

}

catch (InterruptedException e)

{

e.printStackTrace();

}

}

for (int j = 1; j <= 10; j++)

{

System.out.println("sub2 thread sequence of " + j + ",loop of " + i);

}

bShouldSub = 3;

condition3.signal();

}

finally

{

lock.unlock();

}

}


public void sub3(int i)

{

lock.lock();

try

{

while (bShouldSub != 3)

{

try

{

condition3.await();

}

catch (InterruptedException e)

{

e.printStackTrace();

}

}

for (int j = 1; j <= 10; j++)

{

System.out.println("sub3 thread sequence of " + j + ",loop of " + i);

}

bShouldSub = 1;

condition1.signal();

}

finally

{

lock.unlock();

}

}

}