直接上代码:
public class NewThread implements Runnable{
String name;
Thread t;
static boolean suspendFlag;
NewThread(String threadname)
{
name=threadname;
t=new Thread(this,name);
System.out.println("New thread:"+t);
suspendFlag=false;
t.start();
}
public void run()
{
try
{
for(int i=15;i>0;i--)
{
System.out.println(name+":"+i);
Thread.sleep(1000);
synchronized(this){while(suspendFlag){this.wait();}}
}
}catch(InterruptedException e){}
System.out.println(name+" exiting.");
}
synchronized void mysuspend(){suspendFlag=true;}
synchronized void myresume(){suspendFlag=false;notify();}
}
public class SuspendResume {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
NewThread ob1=new NewThread("One");
try{
Thread.sleep(2000);
ob1.mysuspend();
System.out.println("Suspending thread One");
Thread.sleep(2000);
ob1.myresume();
System.out.println("Resuming thread One");
Thread.sleep(2000);
}catch(InterruptedException e){}
try{System.out.println("Waiting for threads to finiish.");
ob1.t.join();
}catch(InterruptedException e){}
System.out.println("Main thread exiting.");
}
}
运行结果:
New thread:Thread[One,5,main]
One:15
One:14
One:13
Suspending thread One
One:12
Resuming thread One
One:11
One:10
Waiting for threads to finiish.
One:9
One:8
One:7
One:6
One:5
One:4
One:3
One:2
One:1
One exiting.
Main thread exiting.
如预期一样,ob1.mysuspend();ob1.myresume();的调用在ob1线程运行中是正常时间控制挂起和重启。
但将run()方法中synchronized(this){}模块稍微修改:
public void run()
{
try
{
synchronized(this){
for(int i=15;i>0;i--)
{
System.out.println(name+":"+i);
Thread.sleep(1000);
while(suspendFlag){this.wait();}
}
}
}catch(InterruptedException e){}
System.out.println(name+" exiting.");
}
其余代码不变
结果是:
New thread:Thread[One,5,main]
One:15
One:14
One:13
One:12
One:11
One:10
One:9
One:8
One:7
One:6
One:5
One:4
One:3
One:2
One:1
Suspending thread One
One exiting.
Resuming thread One
Waiting for threads to finiish.
Main thread exiting.
结果是主线程对ob1.mysuspend();ob1.myresume();的调用没有按照预期的时间进行,而是卡在ob1线程运行结束后才开始调用,就好像ob1得运行将ob1.mysuspend();ob1.myresume();锁住一样,sychonized模块将循环体包围住,mysuspend()就像被锁住不能动了似的,为什么会有两次的运行结果差异?谢谢。
第二种情况的结果的末尾:
One:2
One:1 //线程ob1在synchronized模块中的输出内容。
Suspending thread One //主线程成功调用了ob1.mysuspend()的输出。
One exiting. //线程ob1在synchronized模块外输出内容。
主线程非常巧合的再线程执行完最后一个synchronized模块输出后开始启动。主线程再”等待”ob1中synchroized()模块的结束,双方是互相独立的synchronized锁代码,
怎么会互相等待的呢。
测试了你的代码,运行结果的表象是main线程是在one线程执行完成后才开始执行挂起操作的,单本质是main线程的sleep时间过长,导致操作系统在判断线程优先级的时候,one线程总是比main线程先获取CPU的使用权,导致main线程只能在one线程执行完成后才获得使用权。你只要把main中的sleep时间改小一点,就正常了。
理论上synchronized的监视器对象不同,线程之间是不会相互影响的。而线程之间的CPU竞争则是由操作系统调度的。
补充说明:跟踪测试了发现只要main函数有sleep的话,总是one线程先执行完成后才会由main线程继续执行,就是说操作系统总是将CPU的使用权优先交给了线程one。
如果将main函数中的第一个sleep去掉或者sleep(0)【sleep(0)是指暂时交出CPU使用权,便于操作系统重新进行CPU使用权的分配】的话,CPU使用权又会优先回到main线程中的。所以这个运行结果出现的原因是操作系统在线程优先级调度策略上的问题,并不是ynchronized的原因。祝好!
睿捷:
synchronized这个关键字是个 {...}加锁的,你一个线程起了之后,执行到这里的时候要把synchronized里面的代码执行完之后才会到下一步。你第二个虽然要求当前线程挂起,但是2000毫秒的时候该线程还没有执行完synchronized里面的内容,所以还得继续执行,知道synchronized执行完成后,才开始挂起。当然这个时候挂起也没有什么意义了,线程已经执行完了。你可以试试在synchronized下面在添加一些代码,比如再来一个synchronized,中间判断那个flag,看看会不会中间挂起。