Java Thread.Yield()不暂停当前线程
正如我所读到的关于yield()的内容 它暂停当前线程并执行下一个线程,但为什么不暂停第一个线程呢 请解释它将如何工作 这是我的密码Java Thread.Yield()不暂停当前线程,java,multithreading,Java,Multithreading,正如我所读到的关于yield()的内容 它暂停当前线程并执行下一个线程,但为什么不暂停第一个线程呢 请解释它将如何工作 这是我的密码 public class MyRunnable implements Runnable { public static void main(String[] args) { Thread t1 = new Thread(new MyRunnable()); t1.setName("First"); t1.start();
public class MyRunnable implements Runnable {
public static void main(String[] args) {
Thread t1 = new Thread(new MyRunnable());
t1.setName("First");
t1.start();
Thread t2= new Thread(new MyRunnable());
t2.setName("Second");
t2.start();
for(int i=0; i<5; i++) {
System.out.println("Inside main");
}
}
public void run() {
for(int i=0; i<5; i++) {
System.out.println(Thread.currentThread().getName());
Thread.yield();
}
}
}
This is my output
Inside main
Inside main
Inside main
Inside main
Inside main
First
First
First
First
First
Second
Second
Second
Second
Second
公共类MyRunnable实现Runnable{
公共静态void main(字符串[]args){
线程t1=新线程(new MyRunnable());
t1.集合名(“第一”);
t1.start();
线程t2=新线程(new MyRunnable());
t2.设定名称(“第二”);
t2.start();
对于(inti=0;i有两种可能的解释
首先,Thread.yield()只是对线程调度程序的一个提示,并不保证在当前线程继续运行之前会运行任何其他线程,更不用说所有其他线程了。在Javadoc中,“调度程序可以随意忽略此提示”和“很少适合使用此方法”:
其次,设置一个新线程需要大量的系统处理。可能是第二个线程需要足够长的时间来设置,第一个线程可以在第二个线程准备好打印之前打印五行
一般来说,无法预测线程的运行顺序,在编写多线程代码时,不应指望不同线程中处理之间的顺序,除非显式同步线程。您几乎不应在应用程序中使用文档中所述的:
很少使用这种方法。它可能对调试或测试有用,因为它可能有助于重现由于竞争条件而产生的bug
它不能保证它会做任何事情。如果你想在多线程程序中建立一个排序,考虑更方便的更高级的原语,例如,如果你希望在不同线程中的循环中的五次迭代同步,你可以使用<代码> PHASER < /代码>,例如:
import java.util.concurrent.Phaser;
public class MyRunnable implements Runnable {
Phaser p;
public MyRunnable(Phaser p) {
this.p = p;
}
public static void main(String[] args) {
// We have three parties: main thread and two additional threads
Phaser p = new Phaser(3);
Thread t1 = new Thread(new MyRunnable(p));
t1.setName("First");
t1.start();
Thread t2 = new Thread(new MyRunnable(p));
t2.setName("Second");
t2.start();
for (int i = 0; i < 5; i++) {
System.out.println("Inside main");
// notify Phaser that phase is finished and wait other parties before continue
p.arriveAndAwaitAdvance();
}
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName());
// notify Phaser that phase is finished and wait other parties before continue
p.arriveAndAwaitAdvance();
}
}
}
因此,您可以看到,只有在所有线程中的第一次迭代完成之后,第二次迭代才会开始
[Thread.yield()
…]它暂停当前线程并执行下一个线程
不,那是个误会
Thread.yield()
的目的是在协同多任务系统中运行的程序中创建上下文切换的机会
我不知道这些天在哪里可以找到这样的系统,除了在太小而不能运行Java的微型微控制器上;但很久以前,协作多任务曾经更为常见
大多数现代环境都实现了抢占式多任务:系统可以随时在线程之间切换,而线程甚至不知道发生了什么
在协作多任务系统中,当当前线程执行系统调用时,系统只能在线程之间切换
但是,如果您希望一个线程执行一些长时间运行的后台计算,并且它不需要进行任何系统调用,那么该怎么办呢?您要做的是在计算的关键点添加一些yield()
调用,以便给其他线程一个运行的机会
在现代系统上,您不应该期望Thread.yield()
做任何事情。如果系统负载过重,它可能会将调用线程撞到运行队列的后面,……也可能不会。这取决于库实现者的突发奇想
有一件事它绝对不会做(也从来没有做过),那就是“暂停”线程或“等待”任何事情在调用之前、期间和之后都是可运行的。始终。它没有说明暂停调用线程。这是您编造的。错误!它没有暂停线程,但它通知系统在调用时将切换该线程(上下文切换到另一个线程),
Inside main
Second
First
First
Second
Inside main
Inside main
First
Second
Second
Inside main
First
First
Second
Inside main