线程的yield操作

简介: 线程的yield操作的作用是让出目前正在执行的线程放弃当前的执行,让出CUP权限,使得CPU去执行其他的线程。处于让步状态的JVM层面的线程状态仍然是RUNNABLE状态,但是该线程所对应的操作系统层面的线程从状态上来说会从执行状态编程就绪状态。线程yield时,线程放弃和重占CPU的时间是不确定的,可能是刚刚放弃CPU,马上又获得CPU执行权限,重新开始执行。

线程的yield操作的作用是让出目前正在执行的线程放弃当前的执行,让出CUP权限,使得CPU去执行其他的线程。处于让步状态的JVM层面的线程状态仍然是RUNNABLE状态,但是该线程所对应的操作系统层面的线程从状态上来说会从执行状态编程就绪状态。线程yield时,线程放弃和重占CPU的时间是不确定的,可能是刚刚放弃CPU,马上又获得CPU执行权限,重新开始执行。

yield0方法是Thread类提供的一个静态方法,它可以让当前正在执行的线程暂停,但它不会阻寒该线程,只是让线程转入就绪状态。yield只是让当前线程暂停一下,让系统的线程调度器重新调度一次,yield()方法只有一个版本。

--javascripttypescriptbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

package day07;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
/**
 * yield:
 *  让出CUP时间片,让CUP去调用其他线程。
 *  但是当前线程的状态依然是RUNNABLE
 *  虽然让出时间片,但是有可能,CPU进行调度的时候,依然会继续执行。
 *
 */
public class Demo07 {
    public static final int count = 1000;
    public static AtomicInteger runCount = new AtomicInteger(0);
    public static Map<String,AtomicInteger> map = new HashMap<>();
    public static void main(String[] args) throws InterruptedException {
        MyThread myThread01 = new MyThread();
        MyThread myThread02 = new MyThread();
        myThread01.start();
        myThread02.start();
        Thread.sleep(5000);
        System.out.println(map);
    }
    /**
     * 打印出线程的执行次数
     */
    static class MyThread extends Thread{
        static int threadNum = 1;
        public MyThread() {
            super("Thread-"+threadNum);
            threadNum++;
            map.put(this.getName(), new AtomicInteger(0));
        }
        @Override
        public void run() {
            for (int i = 0; i < count && runCount.get()<count; i++) {
                runCount.incrementAndGet();
                map.get(this.getName()).incrementAndGet();
                if (i % 2 == 0) {
                    Thread.yield();
                }
            }
        }
    }
}

在以上演示案例中,一共启动了两个让步演示线程,两个线程每执行两次操作就让出CPU。但是两个线程的优先级有区别,Thread-1的优先级为10, Thread-2的优先级为1,从输出的结果可以看出,优先级高的 Thread-1执行的次数比优先级低的Thread-2在执行的次数多很多。得到的结论是:线程调用yield之后,操作系统在重新进行线程调度时偏向于将执行机会让给优先级较高的线程。

总结起来,Thread.yield()方法有以下特点:

1)yield仅能使一个线程从运行状态转到就绪状态,而不是阻塞状态。

2)yield不能保证使得当前正在运行的线程状态迅速转到就绪状态。

3)即使完成了迅速切换,系统通过线程调度机制从所有就绪线程中挑选下一个执行线程时,就绪的线程有可能被选中,也有可能不被选中,其调度的过程受其他因素(如优先级)的影响。

相关文章
|
5月前
|
Java
学习多线程之yield方法
学习多线程之yield方法
45 0
|
4月前
|
存储 算法 Linux
一起聊聊内核中的线程:操作函数、进程状态、task_struct、举个例子、
一起聊聊内核中的线程:操作函数、进程状态、task_struct、举个例子、
65 0
|
5月前
|
监控 安全 Windows
4.3 Windows驱动开发:监控进程与线程对象操作
在内核中,可以使用`ObRegisterCallbacks`这个内核回调函数来实现监控进程和线程对象操作。通过注册一个`OB_CALLBACK_REGISTRATION`回调结构体,可以指定所需的回调函数和回调的监控类型。这个回调结构体包含了回调函数和监控的对象类型,还有一个`Altitude`字段,用于指定回调函数的优先级。优先级越高的回调函数会先被调用,如果某个回调函数返回了一个非NULL值,后续的回调函数就不会被调用。当有进程或线程对象创建、删除、复制或重命名时,内核会调用注册的回调函数。回调函数可以访问被监控对象的信息,如句柄、进程ID等,并可以采取相应的操作,如打印日志、记录信息等。
32 0
4.3 Windows驱动开发:监控进程与线程对象操作
|
10月前
|
Java
【Java】Java中让线程休眠一段时间再进行如何操作?
【Java】Java中让线程休眠一段时间再进行如何操作?
95 0
|
Java API 调度
Android C++系列:JNI中的线程操作
第四个参数为线程启动程序的参数,也就是函数的参数,如果不需要传递参数,它可以为 NULL 。 pthread_create 函数如果执行成功了则返回 0 ,如果返回其他错误代码。
185 0
|
存储 Python
Python语言如何在一个单独的线程中进行快速的IO操作
Python语言如何在一个单独的线程中进行快速的IO操作
Python语言如何在一个单独的线程中进行快速的IO操作
|
设计模式 安全 Java
多线程的创建、线程的状态和调度and同步、join和yield以及单例设计模式的种类
多线程的创建、线程的状态和调度and同步、join和yield以及单例设计模式的种类
77 0
|
Java 调度
69. 对并发熟悉吗?谈谈线程间的协作(wait/notify/sleep/yield/join)
69. 对并发熟悉吗?谈谈线程间的协作(wait/notify/sleep/yield/join)
46 1
69. 对并发熟悉吗?谈谈线程间的协作(wait/notify/sleep/yield/join)
【多线程】面试官:如何利用线程工具,防止多线程同时操作一个资源?
通过前面的学习,知道了线程的利与弊,正确的使用多线程,会尽最大的可能去压榨我们系统的资源,从而提高效率,但是如果不合理使用线程,可能会造成副作用,给系统带来更大的压力,进一步的思考,如何才能防止多线程操作一个资源?
|
安全 算法 调度
411操作系统学习笔记——进程与线程、处理机调度、同步与互斥(PV操作)、死锁(四)
411操作系统学习笔记——进程与线程、处理机调度、同步与互斥(PV操作)、死锁
135 1
411操作系统学习笔记——进程与线程、处理机调度、同步与互斥(PV操作)、死锁(四)