先看个yield让步的例子
代码如下 | 复制代码 |
package com.javaer.thread; public class YThread implements Runnable { private Object obj = new Object(); /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub YThread s = new YThread(); Thread t1 = new Thread(s, "Thread1"); Thread t2 = new Thread(s, "Thread2"); t1.start(); t2.start(); } @Override public void run() { for (int i = 0; i < 10; i++) { try { Thread.sleep(10); } catch (InterruptedException e) { } System.out.println(Thread.currentThread().getName() + " 在运行 " + i); if (Thread.currentThread().getName().equals("Thread1")) { Thread.yield(); } } } } 输出 Thread1 在运行 0 |
我们发现尽管从第一次循环就开始让步了,不过系统在第二次循环才真正让出资源。另外,如果多次执行这个代码,发现有时候根本没有让出来。
结论
让步会主动让出系统资源给其他线程,但是不代表让步了,其他线程就能获得CPU资源。另外让步不影响自己线程继续执行。类似两个车子在路上开,给别人让路不代表我要停下。
看下让步与锁的相互作用
代码如下 | 复制代码 |
package com.javaer.thread; public class YThread implements Runnable{ private Object obj = new Object(); /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub YThread s= new YThread(); Thread t1 = new Thread(s, "Thread1"); Thread t2 = new Thread(s, "Thread2"); t1.start(); t2.start(); } @Override public void run() { synchronized(obj){ for(int i =0 ; i < 10;i++){ try { Thread.sleep(10); } catch (InterruptedException e) { } System.out.println(Thread.currentThread().getName() + " 在运行 " + i); if(Thread.currentThread().getName().equals("Thread1")){ Thread.yield(); } } } } } |
我们知道,wait()的作用是让当前线程由“运行状态”进入“等待(阻塞)状态”的同时,也会释放同步锁。而yield()的作用是让步,它也会让当前线程离开“运行状态”。它们的区别是:
(01) wait()是让线程由“运行状态”进入到“等待(阻塞)状态”,而不yield()是让线程由“运行状态”进入到“就绪状态”。
(02) wait()是会线程释放它所持有对象的同步锁,而yield()方法不会释放锁。
上面的结果看出,程序整个被锁定,进行了顺序执行
Thread1 在运行 0
Thread1 在运行 1
Thread1 在运行 2
Thread1 在运行 3
Thread1 在运行 4
Thread1 在运行 5
Thread1 在运行 6
Thread1 在运行 7
Thread1 在运行 8
Thread1 在运行 9
Thread2 在运行 0
Thread2 在运行 1
Thread2 在运行 2
Thread2 在运行 3
Thread2 在运行 4
Thread2 在运行 5
Thread2 在运行 6
Thread2 在运行 7
Thread2 在运行 8
Thread2 在运行 9
总结
yield()的作用是让步。它能让当前线程由“运行状态”进入到“就绪状态”,从而让其它具有相同优先级的等待线程获取执行权;但是,并不能保证在当前线程调用yield()之后,其它具有相同优先级的线程就一定能获得执行权;也有可能是当前线程又进入到“运行状态”继续运行!
1.仅仅是让步
2.不会释放锁