java多线程,让步yield

[seriesposts sid=500]

先看个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
Thread2 在运行 0
Thread1 在运行 1
Thread2 在运行 1
Thread2 在运行 2
Thread1 在运行 2
Thread2 在运行 3
Thread1 在运行 3
Thread2 在运行 4
Thread1 在运行 4
Thread2 在运行 5
Thread1 在运行 5
Thread2 在运行 6
Thread1 在运行 6
Thread2 在运行 7
Thread1 在运行 7
Thread2 在运行 8
Thread1 在运行 8
Thread2 在运行 9
Thread1 在运行 9

我们发现尽管从第一次循环就开始让步了,不过系统在第二次循环才真正让出资源。另外,如果多次执行这个代码,发现有时候根本没有让出来。

结论

让步会主动让出系统资源给其他线程,但是不代表让步了,其他线程就能获得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.不会释放锁


This entry was posted in JAVA and tagged , , , . Bookmark the permalink.
月小升QQ 2651044202, 技术交流QQ群 178491360
首发地址:月小升博客https://java-er.com/blog/java-yield-thread/
无特殊说明,文章均为月小升原创,欢迎转载,转载请注明本文地址,谢谢
您的评论是我写作的动力.
2020.03.24 评论已经全局关闭,有事加QQ聊天