下面2个代码一个是用flag+while 控制执行(200ms 监控一次)
一个则是用wait notify 控制执行我想知道他们的效率(也就是CPU使用率)是不是差别非常多public class WNvsWhileLoopTest implements Runnable { private static Lock l = new Lock(); @Override
public synchronized void run() {
try {
synchronized (l) { Thread.sleep(5000);
l.notify();
Thread.yield();
Thread.sleep(10000);
Thread2.lockFlag = true; }
} catch (InterruptedException e) {
e.printStackTrace();
}
} public static void main(String[] args) {
new Thread(new Thread1(l)).start();
new Thread(new Thread2()).start();
new Thread(new WNvsWhileLoopTest()).start(); }}class Thread1 implements Runnable { private Lock lock = null; public Thread1(Lock l) {
this.lock = l;
} @Override
public void run() {
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread1 Lock released!");
} }}class Thread2 implements Runnable { public static boolean lockFlag = false; @Override
public void run() {
while (true) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (lockFlag) {
System.out.println("Thread2 Lock released!");
break;
}
}
}}class Lock {
}
还有一个问题  就是为什么Thread1比Thread2后released?
因为我是先thread1.notify  然后再把thread2跳出while的

解决方案 »

  1.   

    你的程序写的就不对吧
    能通过编译吗?implements Runnable
    @Override
    public void run() 
      

  2.   


    synchronized是可以加到run上面的 只是一般的重写而已哇
      

  3.   

    我建议是用JProfiler搞一下  凭感觉我觉得while(true) 会高很多
      

  4.   

    notify只是使处于锁池中的对象的状态转变为等待池,这时候都还没有到达就绪状态,怎么可能运行的了
    楼上的那个重写的标注怎么错了,线程的使用确实只有两种方法,一个是实现Runnable接口,另一个就是继承
    Thread类,都得重写run方法,并调用start方法。
      

  5.   


    继承接口,方法叫实现,不是重写
    @Override,当然错了
      

  6.   


    实现接口,实现接口中的方法,不是重写
    @Override,当然错了
    在9楼说的不严谨
      

  7.   

    我觉得这就是2种不同的资源调控的方式。使用while毫无疑问会浪费cpu去做轮询的操作。而使用wait-notify操作则会避免这种情形。说白了,主动式和被动式的区别。
      

  8.   

    结果是 真正使用CPU时间片的时间:
    Thread2 大约1031纳秒        86.9%
       
    Thread Main    大约44纳秒   3.7%Thread 1       112纳秒      9.4%也就是 86.9:9.4所以 notify+wait的效率是 while(true) 的 9倍
      

  9.   


    public synchronized void run() {
            try {
                synchronized (l) {                Thread.sleep(2000);
                    l.notify();        
                    Thread.yield();   
                    Thread.sleep(4000);
                    Thread2.lockFlag = true;
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    楼主在你的方法里面在Thread2.lockFlag = true;后再sleep一下就能看出来三个线程的执行关系了。
    Thread1在WNvsWhileLoopTest 里面被唤醒,但是此时Thread1中的lock被同步着,所以Thread1只有在WNvsWhileLoopTest线程结束之后才可能取到lock对象的引用,所以Thread1一定是在WNvsWhileLoopTest 结束之后才能执行。如果不相信或者不理解,可以再改下代码:
    synchronized (l) {                Thread.sleep(2000);
                    l.notify();        
                    Thread.yield();   
                    Thread.sleep(4000);
                    Thread2.lockFlag = true;
                    Thread.sleep(10000);         //增大WNvsWhileLoopTest 睡眠时间
                }
    你会发现,在Thread2输出很久之后Thread1才会运行。所以说,用Thread2的方法可以随时启动线程,但是Thread1得方法只能等到同步线程结束之后才能运行。至于效率,得看你的需求了。
    如果需要等待的时间不长,Thread1我比较支持,他能有效解决同步问题。
    如果同步线程等待时间较长又对数据同步没什么需求的话,Thread2比Thread1效率好。至于楼主说的问题是因为没有在Thread2.lockFlag = true;的同时WNvsWhileLoopTest系统调用Thread2和Thread1和先后顺序不可预见,所以两种情况都可能发生。
    若像上面代码那样测试的话不会出现楼主所见问题,或者:
    Thread.yield();   
               Thread2.lockFlag = true;
               Thread.sleep(4000);
    顺序改下肯定不会发生类似问题。
      

  10.   

    上面说错了,应该是
    短时间的线程占用Thread2就行,差别不大;
    如果是长时间肯定Thread1优于Thread2的。
    说反了