下面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的
一个则是用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的
能通过编译吗?implements Runnable
@Override
public void run()
synchronized是可以加到run上面的 只是一般的重写而已哇
楼上的那个重写的标注怎么错了,线程的使用确实只有两种方法,一个是实现Runnable接口,另一个就是继承
Thread类,都得重写run方法,并调用start方法。
继承接口,方法叫实现,不是重写
@Override,当然错了
实现接口,实现接口中的方法,不是重写
@Override,当然错了
在9楼说的不严谨
Thread2 大约1031纳秒 86.9%
Thread Main 大约44纳秒 3.7%Thread 1 112纳秒 9.4%也就是 86.9:9.4所以 notify+wait的效率是 while(true) 的 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);
顺序改下肯定不会发生类似问题。
短时间的线程占用Thread2就行,差别不大;
如果是长时间肯定Thread1优于Thread2的。
说反了