Java的Thread测试[包括sleep,wait的使用比较]
package javaBese;
public class ThreadTest {
/*
* 共同点: 他们都是在多线程的环境下,都可以在程序的调用处阻塞指定的毫秒数,并返回。
?? 不同点: Thread.sleep(long)可以不在synchronized的块下调用,而且使用Thread.sleep()不会丢失当前线程对任何对象的同步锁(monitor);
??????????????? object.wait(long)必须在synchronized的块下来使用,调用了之后失去对object的monitor, 这样做的好处是它不影响其它的线程对object进行操作。
?? */
public void thread()
{
?? System.out.println("I am here!");
??
?? Thread thread = new Thread();
?? Thread thread2 = new Thread();
?? try {
???
??? thread2.sleep(1000);
??? System.out.println("sleep 1秒后,I am come back!");
???
??? thread2.start();
??? System.out.println("thread is start");
???
??? thread2.stop();
??? System.out.println("thread is stop");
???
??? synchronized (thread)//如果使用wait,就必须synchronized来同步对象
??? {
???? System.out.println("");
???? for (int i = 0; i < 5; i++) {
????? thread.notify();//必须要放在synchronized方法的里面
????? System.out.println("First,notify thread");
????? thread.wait(1000);
????? System.out.println("wait 1秒后,I am come back!");
???? }
??? }
?? } catch (Exception e) {
??? // TODO Auto-generated catch block
??? e.printStackTrace();
?? }
}
public static void main(String[] args) {
?? ThreadTest threadTest = new ThreadTest();
?? threadTest.thread();
}
}
/*
* 复杂应用
程序会启动20个线程,20个线程都使用同一个sync的object(名字为SYNC)。 线程启动代码如下:
Java代码
final TC[] ts = new TC[20];??
??????? for (int i = 0; i < ts.length; i++) {??
??????????? TC target = new TC("TC " + i, SYNC1);??
??????????? Thread thread = new Thread(target);??
??????????? ts[i] = target;??
??????????? thread.start();??
}
final TC[] ts = new TC[20];
??????? for (int i = 0; i < ts.length; i++) {
??????????? TC target = new TC("TC " + i, SYNC1);
??????????? Thread thread = new Thread(target);
??????????? ts[i] = target;
??????????? thread.start();
}
------------------------
接下来马上启动另外一个线程用于做notify操作。
Java代码
// 一个用于停止的Thread??
??????? new Thread(new Runnable() {??
??????????? public void run() {??
??????????????? synchronized (SYNC1) {??
??????????????????? int i = 10;??
??????????????????? while (i > 0) {??
??????????????????????? System.out.println("Now will notify the thread " + i);??
??????????????????????? ts[i].notifySelf();??
??????????????????????? try {??
??????????????????????????? SYNC1.wait(10000);??
??????????????????????? } catch (InterruptedException e) {??
??????????????????????????? e.printStackTrace();??
??????????????????????? }??
??????????????????????? i--;??
??????????????????? }??
??????????????? }??
??????????? }??
}).start();
// 一个用于停止的Thread
??????? new Thread(new Runnable() {
??????????? public void run() {
??????????????? synchronized (SYNC1) {
??????????????????? int i = 10;
??????????????????? while (i > 0) {
??????????????????????? System.out.println("Now will notify the thread " + i);
??????????????????????? ts[i].notifySelf();
??????????????????????? try {
??????????????????????????? SYNC1.wait(10000);
??????????????????????? } catch (InterruptedException e) {
??????????????????????????? e.printStackTrace();
??????????????????????? }
??????????????????????? i--;
??????????????????? }
??????????????? }
??????????? }
}).start();
------------------------
Java代码
启动的TC线程代码如下:??
class TC implements Runnable {??
??? private final String name;??
??? private final Object sync;??
??? private boolean isRunning = false;??
??? public TC(String name, Object sync) {??
??????? this.name = name;??
??????? this.sync = sync;??
??? }??
??? public void run() {??
??????? synchronized (sync) {??
??????????? while (true) {??
??????????????? // 每个线程默认都加入线程池排队。这样有助于打乱线程在主线程中启动的顺序,方便后面的观测。??
??????????????? if (!isRunning) {??
??????????????????? try {??
??????????????????????? sync.wait(1000);??
??????????????????? } catch (InterruptedException e) {??
??????????????????????? e.printStackTrace();??
??????????????????? }??
??????????????????? isRunning = true;??
??????????????? }??
??????????????? System.out.println(name + " Running .......");??
??????????????? try {??
??????????????????? sync.wait();??
??????????????? } catch (InterruptedException e) {??
??????????????????? e.printStackTrace();??
??????????????? }// Wait 1 second??
??????????? }??
??????? }??
??? }??
??? public void notifySelf() {??
??????? synchronized (sync) {??
??????????? System.out.println("Coming to notify the thread " + name);??
??????????? sync.notify();??
??????? }??
??? }??
}
启动的TC线程代码如下:
class TC implements Runnable {
??? private final String name;
??? private final Object sync;
??? private boolean isRunning = false;
??? public TC(String name, Object sync) {
??????? this.name = name;
??????? this.sync = sync;
??? }
??? public void run() {
??????? synchronized (sync) {
??????????? while (true) {
??????????????? // 每个线程默认都加入线程池排队。这样有助于打乱线程在主线程中启动的顺序,方便后面的观测。
??????????????? if (!isRunning) {
??????????????????? try {
??????????????????????? sync.wait(1000);
??????????????????? } catch (InterruptedException e) {
??????????????????????? e.printStackTrace();
??????????????????? }
??????????????????? isRunning = true;
??????????????? }
??????????????? System.out.println(name + " Running .......");
??????????????? try {
??????????????????? sync.wait();
??????????????? } catch (InterruptedException e) {
??????????????????? e.printStackTrace();
??????????????? }// Wait 1 second
??????????? }
??????? }
??? }
??? public void notifySelf() {
??????? synchronized (sync) {
??????????? System.out.println("Coming to notify the thread " + name);
??????????? sync.notify();
??????? }
??? }
}
---------------------------分割线---------------------------------
输出日志如下(//部分是我加的注释,不是实际输出):
Now will notify the thread 10 //首先试着notify第10个TC
Coming to notify the thread TC 10 // 也确实调用了SYNC的notify操作,但是因为当前还没有任何线程在wait,所以这个notify信号就被丢弃掉了。这个notify过去就过去了。不会影响后面的任何操作了。
TC 1 Running .......
TC 5 Running .......
TC 0 Running .......
TC 2 Running .......
TC 4 Running .......
TC 6 Running .......
TC 8 Running .......
TC 10 Running .......
TC 12 Running .......
TC 14 Running .......
TC 7 Running .......
TC 9 Running .......
TC 11 Running .......
TC 13 Running .......
TC 15 Running .......
TC 17 Running .......
TC 3 Running .......
TC 18 Running .......
TC 16 Running .......
TC 19 Running ....... //启动20线程,这20个线程启动的顺序已经被打乱了。不会从头到尾1-20的启动,而是如log显示1,5,0,2,4,6,8,10,12,14.........
//每个线程启动后会被wait(). wait的顺序是1,5,0,2,4,6,8,10,12,14.........
Now will notify the thread 9
Coming to notify the thread TC 9
TC 1 Running .......
Now will notify the thread 8
Coming to notify the thread TC 8
TC 5 Running .......
Now will notify the thread 7
Coming to notify the thread TC 7
TC 0 Running .......
Now will notify the thread 6
Coming to notify the thread TC 6
TC 2 Running .......
Now will notify the thread 5
Coming to notify the thread TC 5
TC 4 Running .......
Now will notify the thread 4
Coming to notify the thread TC 4
TC 6 Running .......
Now will notify the thread 3
Coming to notify the thread TC 3
TC 8 Running .......
Now will notify the thread 2
Coming to notify the thread TC 2
TC 10 Running .......
Now will notify the thread 1
Coming to notify the thread TC 1
TC 12 Running .......
//总共10个notify操作,但是因为启动的时候一个notify因为没有任何wait的线程给丢弃了,所以,这里只有9个notify起到了作用。他们是按照进入pool的顺序排队给notify。
//一个notify操作仅仅激活一个wait队列中的第一个线程。一对一操作。
-------------------------------分割线------------------------------
使用notifyAll代替notify。
日志输出:
Now will notify the thread 10
Coming to notify the thread TC 10 //第一个notifyAll的操作还是被丢弃了
TC 0 Running .......
TC 1 Running .......
TC 3 Running .......
TC 5 Running .......
TC 7 Running .......
TC 9 Running .......
TC 11 Running .......
TC 13 Running .......
TC 15 Running .......
TC 17 Running .......
TC 19 Running .......
TC 2 Running .......
TC 4 Running .......
TC 6 Running .......
TC 8 Running .......
TC 10 Running .......
TC 12 Running .......
TC 14 Running .......
TC 16 Running .......
TC 18 Running .......
Now will notify the thread 9
Coming to notify the thread TC 9 //一个notifyAll的操作notify所以正在wait的线程。
TC 0 Running .......
TC 1 Running .......
TC 3 Running .......
TC 5 Running .......
TC 7 Running .......
TC 9 Running .......
TC 11 Running .......
TC 2 Running .......
TC 13 Running .......
TC 15 Running .......
TC 4 Running .......
TC 17 Running .......
TC 19 Running .......
TC 6 Running .......
TC 8 Running .......
TC 10 Running .......
TC 12 Running .......
TC 14 Running .......
TC 16 Running .......
TC 18 Running .......
* */
?
?
?
转自:http://hi.baidu.com/billgon/blog/item/503fb458997888cc9c820490.html