线程优先级

线程的优先级将该线程的重要性传递给线程调度器,调度器将倾向于让优先权最高的线程先执行.然后这并不意味值优先权较低的线程将得不到执行.优先级较低的线程仅仅是执行的频率较低

package com.yin.myproject.demo.concurrent.base;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SimplePriorities implements Runnable {
private int countDown = 5;
private volatile double d;
private int priority;

public SimplePriorities(int priority) {
this.priority = priority;
}

public String toString() {
return "name:" + Thread.currentThread().getName() + " priority: " + Thread.currentThread().getPriority()
+ ":prority:" + ": " + countDown;
}

public void run() {
Thread.currentThread().setPriority(priority);
while (true) {
for (int i = 1; i < 10000; i++) {
d += (Math.PI + Math.E) / (double) i;
if (i % 1000 == 0) {
Thread.yield();
}
}
System.out.println(this);
if (--countDown == 0)
return;
}
}

public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
for (int i = 0; i < 5; i++) {
exec.execute(new SimplePriorities(Thread.MIN_PRIORITY));
exec.execute(new SimplePriorities(Thread.MAX_PRIORITY));
}
exec.shutdown();
}
}

输出结果(每次执行结果都会有所偏差):

name:pool-1-thread-6 priority: 10: 5
name:pool-1-thread-3 priority: 1: 5
name:pool-1-thread-4 priority: 1: 5
name:pool-1-thread-1 priority: 1: 5
name:pool-1-thread-5 priority: 1: 5
name:pool-1-thread-2 priority: 1: 5
name:pool-1-thread-1 priority: 1: 4
name:pool-1-thread-6 priority: 10: 4
name:pool-1-thread-4 priority: 1: 4
name:pool-1-thread-3 priority: 1: 4
......

从执行结果上我们可以总结为一下两点:
1. 线程优先级并不能保证线程的执行顺序,优先级高的并不一定先执行,优先级低的也不一定不执行
2. 不要试图使用优先级来控制线程的执行顺序

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.

大体意思是说,当调用Thread.yield()函数时,会给线程调度器一个当前线程愿意让出CPU使用的暗示,但是线程调度器可能会忽略这个暗示。通俗的解释就是当前线程愿意让出CPU的使用权,可以让其他线程继续执行,但是线程调度器可能会停止当前线程继续执行,也可能会让该线程继续执行。
下面通过一个例子来演示Thread.yield()函数的使用:

public class YieldDemo01 {
public static void main(String[] args) {
YieldThread t1 = new YieldThread("线程一");
YieldThread t2 = new YieldThread("线程二");
t1.start();
t2.start();
}
}

class YieldThread extends Thread {
private String name;

public YieldThread(String name) {
this.name = name;
}

@Override
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println(name + i);
if (i == 5) {
Thread.yield();
}
}
}
}

每次运行的结果都可能会有偏差,但是注意线程一5和线程二5之后的执行结果。
另一种理解:在网上还存在另一种理解,当调用Thread.yield()函数后,当前线程会被停止,继而其他线程会争夺cpu的控制权,因此有可能是当前线程获得执行,也可能其他线程获得执行. 根据官方文档和Thinking In Java上的讲解,可以确定这种理解是错误的.当调用Thread.yiele()时,没有任何机制可以保证当前线程一定会被停止

总结

可以看出,不管优先级和yield()函数都是试图控制线程的顺序执行.但是我们需要注意的一点是,在java中没有任何机制可以保证线程的执行顺序,两种做法只不过是增加了线程之间切换的几率而已.

更多相关文章

  1. java多线程爬虫
  2. javafx 和netty 混合使用出现线程不一致问题,求大神指点
  3. Java多线程之Thread、Runnable、Callable及线程池
  4. Java,Socket&TCP编程 实现多线程端对端通信与文件传输
  5. Java错误:线程“main”中的异常java.lang.ArrayIndexOutOfBoundsE
  6. Java并发面试题:三个线程轮流打印十次abc
  7. 【java】线程安全的整型类AtomicInteger
  8. Java多线程编程
  9. 线程“main”中的异常java.lang.RuntimeException:无法编译的源代

随机推荐

  1. android > Android 音频均衡器,可通过拖动
  2. Android Activity 启动详解
  3. Android欢迎界面引导页
  4. Android Sqlite轻量级数据库框架
  5. android 对话框的封装
  6. android获取内部外部存储空间
  7. Android手机游戏开发入门教程
  8. android创建类似QQ的android弹出菜单
  9. Android 支持多屏幕机制
  10. android 开发中java.net.UnknownServiceE