class MyThread implements Runnable{ public void run(){ for(int i=0;i<8;i++){ if (i==4){ //如果i==4,则进行礼让一次 System.out.println(Thread.currentThread().getName()+"进行了礼让一次"+"-->"+i); Thread.currentThread().yield();//进行礼让 } System.out.println("执行"+Thread.currentThread().getName()+"-->"+i);
} } } public class P292_1{ public static void main(String args[]){ Thread th1=new Thread(new MyThread(),"线程A"); Thread th2=new Thread(new MyThread(),"线程B"); th1.start(); th2.start();
} }
LZ啊,这个方法正式代码里一般不要用因为jvm并不保证该方法有效
《Java Concurrency in Practice》12.1.6有这么一句话:The effectiveness of this technique is platform-specific, since the JVM is free to treat THRead.yield as a no-op [JLS 17.9]; using a short but nonzero sleep would be slower but more reliable.) 上面提到的JLS 17.9是这么写的: Thread.sleep causes the currently executing thread to sleep (temporarily cease execution) for the specified duration, subject to the precision and accuracy of system timers and schedulers. The thread does not lose ownership of any monitors, and resumption of execution will depend on scheduling and the availability of processors on which to execute the thread. Neither a sleep for a period of zero time nor a yield operation need have observable effects.It is important to note that neither Thread.sleep nor Thread.yield have any synchronization semantics. In particular, the compiler does not have to flush writes cached in registers out to shared memory before a call to Thread.sleep or Thread.yield, nor does the compiler have to reload values cached in registers after a call to Thread.sleep or Thread.yield.
JLS SE7版本中移除了JLS第三版中的那句话,原因在于: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6584700 不过新版API关于yield的描述更加详细:http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#yield() public static void yield() A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore this hint. Yield is a heuristic attempt to improve relative progression between threads that would otherwise over-utilise a CPU. Its use should be combined with detailed profiling and benching to ensure that it actually has the desired effect.It is rarely appropriate to use this method. It may be useful for debugging or testing purposes, where it may help to reproduce bugs due to race conditions. It may also be useful when designing concurrency control constructs such as the ones in the java.util.concurrent.locks package.
好吧,总体意思就是jdk1.6及之前的yield方法的API描述是不详细的,在jdk1.7的API中做了修正,jdk1.7 javadoc关于yield方法的描述如下:A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore this hint.Yield is a heuristic attempt to improve relative progression between threads that would otherwise over-utilise a CPU. Its use should be combined with detailed profiling and benching to ensure that it actually has the desired effect.It is rarely appropriate to use this method. It may be useful for debugging or testing purposes, where it may help to reproduce bugs due to race conditions. It may also be useful when designing concurrency control constructs such as the ones in the java.util.concurrent.locks package.由之前的一句话变成好几段,信息丰富的,也清楚明了了。这里你只需看第一段即可,翻译如下: 暗示调度器当前线程想让出正在使用的处理器。调度器可自由地忽略这种暗示。 ----------------------- 如同System.gc方法一样,暗示jvm要进行垃圾回收了,但jvm可以不理你
还有最后一段的第一句话也很重要:It is rarely appropriate to use this method极少有要使用这个方法的时候
class MyThread implements Runnable{
public void run(){
for(int i=0;i<8;i++){
if (i==4){ //如果i==4,则进行礼让一次
System.out.println(Thread.currentThread().getName()+"进行了礼让一次"+"-->"+i);
Thread.currentThread().yield();//进行礼让
}
System.out.println("执行"+Thread.currentThread().getName()+"-->"+i);
}
}
}
public class P292_1{
public static void main(String args[]){
Thread th1=new Thread(new MyThread(),"线程A");
Thread th2=new Thread(new MyThread(),"线程B");
th1.start();
th2.start();
}
}
上面提到的JLS 17.9是这么写的:
Thread.sleep causes the currently executing thread to sleep (temporarily cease execution) for the specified duration, subject to the precision and accuracy of system timers and schedulers. The thread does not lose ownership of any monitors, and resumption of execution will depend on scheduling and the availability of processors on which to execute the thread.
Neither a sleep for a period of zero time nor a yield operation need have observable effects.It is important to note that neither Thread.sleep nor Thread.yield have any synchronization semantics. In particular, the compiler does not have to flush writes cached in registers out to shared memory before a call to Thread.sleep or Thread.yield, nor does the compiler have to reload values cached in registers after a call to Thread.sleep or Thread.yield.
定义线程A ThreadA{System.out.println("a");};定义线程B TrheadB{System.out.println("b");}public static void main(){
ThreadA a=new ....;
THreadB b=new ....;
for(10){
a.start();//打印10次
}
a.yield();//线程a让步
a.sleep(300);//让线程a休眠300毫秒,为了让线程b所需资源被全部调用并被执行。
b.start();//执行线程b
}
如果不加让a休眠300毫秒,结果应该是a打印10以上,然后b运行。
加上休眠300毫秒时间,结果就是a打印10次,然后b运行。加上300毫秒,为了让线程b所需资源被全部调用就绪,准备被执行。
这个结果正好验证了上面所说的线程调度最优的算法思想。
public void run(){
for(int i=0;i<50;i++){
System.out.println("执行a线程");
}
}
}
class ThreadB implements Runnable{
public void run(){
for(int i=0;i<50;i++){
System.out.println("执行b线程");
}
}
}
class P292_2{
public static void main(String args[]){
Thread a=new Thread(new ThreadA(),"线程A");
Thread b=new Thread(new ThreadB(),"线程B");
a.start();
a.yield();//线程a让步
try{
a.sleep(300); }catch(Exception e){}
b.start();
}
}
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6584700
不过新版API关于yield的描述更加详细:http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#yield()
public static void yield()
A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore this hint.
Yield is a heuristic attempt to improve relative progression between threads that would otherwise over-utilise a CPU. Its use should be combined with detailed profiling and benching to ensure that it actually has the desired effect.It is rarely appropriate to use this method. It may be useful for debugging or testing purposes, where it may help to reproduce bugs due to race conditions. It may also be useful when designing concurrency control constructs such as the ones in the java.util.concurrent.locks package.
暗示调度器当前线程想让出正在使用的处理器。调度器可自由地忽略这种暗示。
-----------------------
如同System.gc方法一样,暗示jvm要进行垃圾回收了,但jvm可以不理你
谢谢了。我明白了。
暗示调度器当前线程想让出正在使用的处理器。调度器可自由地忽略这种暗示。
也就是说。用yield()让出了资源。并不是100%就让别的进程去使用资源。很有可能自己礼让了。下一次使用资源的仍然是自己。对吧。