精华内容
参与话题
问答
  • Java线程调度方式

    2018-04-12 10:40:00
    这小节关注线程如何进行调度,了解了java线程调度模式有助于后面并发框架的深入探讨。 一般线程调度模式分为两种——抢占式调度和协同式调度。抢占式调度指的是每条线程执行的时间、线程的切换都由系统控制,...

    Java多线程环境中,为保证所有线程的执行能按照一定的规则执行,JVM实现了一个线程调度器,它定义了线程调度的策略,对于CPU运算的分配都进行了规定,按照这些特定的机制为多个线程分配CPU的使用权。这小节关注线程如何进行调度,了解了java线程调度模式有助于后面并发框架的深入探讨。

    一般线程调度模式分为两种——抢占式调度和协同式调度。抢占式调度指的是每条线程执行的时间、线程的切换都由系统控制,系统控制指的是在系统某种运行机制下,可能每条线程都分同样的执行时间片,也可能是某些线程执行的时间片较长,甚至某些线程得不到执行的时间片。在这种机制下,一个线程的堵塞不会导致整个进程堵塞。协同式调度指某一线程执行完后主动通知系统切换到另一线程上执行,这种模式就像接力赛一样,一个人跑完自己的路程就把接力棒交接给下一个人,下个人继续往下跑。线程的执行时间由线程本身控制,线程切换可以预知,不存在多线程同步问题,但它有一个致命弱点:如果一个线程编写有问题,运行到一半就一直堵塞,那么可能导致整个系统崩溃。

     

    2-5-6-1

    为更加形象说明两种模式的不同,看图2-5-6-1,左边为抢占式线程调度,假如三条线程需要运行,处理器运行的路径是在线程一运行一个时间片后强制切换到线程二运行一个时间片,然后切到线程三,再回到线程一,如此循环直至三条线程都执行完。而协同式线程调度则不这样走,它会先将线程一执行完,线程一再通知线程二执行,线程二再通知线程三,直到线程三执行完。

    在了解了两种线程调度模式后,现在考虑Java使用的是哪种线程调度模式。此问题的讨论涉及到JVM的实现,JVM规范中规定每个线程都有优先级,且优先级越高越优先执行,但优先级高并不代表能独自占用执行时间片,可能是优先级高得到越多的执行时间片,反之,优先级低的分到的执行时间少但不会分配不到执行时间。JVM的规范没有严格地给调度策略定义,我想正是因为面对众多不同调度策略,JVM要封装所有细节提供一个统一的策略不太现实,于是给了一个不严谨但足够统一的定义。回到问题上,Java使用的线程调度是抢占式调度,在JVM中体现为让可运行池中优先级高的线程拥有CPU使用权,如果可运行池中线程优先级一样则随机选择线程,但要注意的是实际上一个绝对时间点只有一个线程在运行(这里是相对于一个CPU来说,如果你的机器是多核的还是可能多个线程同时运行的),直到此线程进入非可运行状态或另一个具有更高优先级的线程进入可运行线程池,才会使之让出CPU的使用权,更高优先级的线程抢占了优先级低的线程的CPU。

    Java中线程会按优先级分配CPU时间片运行,那么线程什么时候放弃CPU的使用权?可以归类成三种情况:

    1. 当前运行线程主动放弃CPU,JVM暂时放弃CPU操作(基于时间片轮转调度的JVM操作系统不会让线程永久放弃CPU,或者说放弃本次时间片的执行权),例如调用yield()方法。

    2. 当前运行线程因为某些原因进入阻塞状态,例如阻塞在I/O上。

    3. 当前运行线程结束,即运行完run()方法里面的任务。

    三种情况中第三种很好理解,任务执行完了自然放弃CPU,前两种情况用两个例子说明,先看使用yield放弃CPU什么情况:

    public class YeildThread {

    publicstatic void main(String[] args) {

        MyThreadmt = new MyThread();

        mt.start();

        while(true) {

             System.out.println("主线程");

        }

    }

    }

     

    class MyThread extends Thread {

    publicvoid run() {

        while(true) {

             System.out.println("被放弃线程");

             Thread.currentThread().yield();

        }

    }

    }

    截取某段输出如下,输出“主线程”比“被放弃线程”运行的机会多,因为mt线程每次循环都把时间片让给主线程,正是因为yield操作并不会永远放弃CPU,仅仅只是放弃了此次时间片,把剩下的时间让给别的线程,

    主线程

    主线程

    主线程

    主线程

    主线程

    主线程

    被放弃线程

    主线程

    主线程

    主线程

    主线程

    主线程

    主线程

    主线程

     

    第二个例子为节省代码量将使用伪代码表示,例子简单但已能说明问题,运行程序将有两条线程工作,ioThread每次遇到I/O阻塞就放弃当前的时间片,而主线程则按JVM分配的时间片正常运行。

    public class IOBlockThread {

    publicstatic void main(String[] args) {

         IOThread ioThread = new IOThread();

         ioThread.start();

        主线程任务执行

    }

    }

     

    class IOThread extends Thread {

    publicvoid run() {

        while(true) {

             I/O阻塞

        }

    }

    }

     

    Java的线程的调度机制都由JVM实现,假如有若干条线程,你想让某些线程拥有更长的执行时间,或某些线程分配少点执行时间,这时就涉及“线程优先级”,Java把线程优先级分成10个级别,线程被创建时如果没有明确声明则使用默认优先级,JVM将根据每个线程的优先级分配执行时间的概率。有三个常量Thread.MIN_PRIORITY、Thread.NORM_PRIORITY、Thread.MAX_PRIORITY分别表示最小优先级值(1)、默认优先级值(5)、最大优先级值(10)。

    由于JVM的实现以宿主操作系统为基础,所以Java优先级值与各种不同操作系统的原生线程优先级必然存在某种映射关系,这样才足以封装所有操作系统的优先级提供统一优先级语义。例如1-10优先级值在linux可能要与0-99优先级值进行映射,而windows系统则有7个优先级要映射。

    线程的调度策略决定上层多线程运行机制,JVM的线程调度器实现了抢占式调度,每条线程执行的时间由它分配管理,它将按照线程优先级的建议对线程执行的时间进行分配,优先级越高,可能得到CPU的时间则越长。

    转载于:https://www.cnblogs.com/kexianting/p/8805955.html

    展开全文
  • java线程的调度主要有二种方式:(1)协同式执行(2)抢占式执行 (1)协同式执行就是一个线程执行完毕通知操作系统去执行另外一个线程,因此多线程执行,不会出现同步的问题,但是如果一个线程的执行时间很长的话...

    java线程的调度主要有二种方式:(1)协同式执行(2)抢占式执行

    (1)协同式执行就是一个线程执行完毕通知操作系统去执行另外一个线程,因此多线程执行,不会出现同步的问题,但是如果一个线程的执行时间很长的话,可能导致系统崩溃的问题。

    (2)抢占式执行,线程的执行时间是由操作系统决定。操作系统采用时间片轮转的算法,去执行每一个线程。我们用户也可以给线程设置优先级,优先级高的先执行,优先级低的后执行。但是,线程的执行需要映射到操作系统上,因此有时候采用优先级的方式肯能不好使。


    线程的几种状态:

    创建:线程创建未启动 Thread thread=new Thread()

    运行:thread.start();

    无限等待:Object.wait() Object.notify()

    有限等待:Thread.sleep(long timeout) Object.wait() Object.notify(long timeout)

    阻塞:synchronized 线程进入同步区,就会阻塞

    结束:线程执行结束



    展开全文
  • Java线程的调度

    2018-05-03 08:28:59
    线程调度一般指是系统为线程分配处理器使用权过程,这个过程会产生上下文切换,即操作系统CPU利用时间片轮转的方式给每个任务分配一定执行时间,然后把当前任务状态保存下来,接着加载下一任务状态并执行...

    线程调度一般指的是系统为线程分配处理器使用权的过程,这个过程会产生上下文切换,即操作系统的CPU利用时间片轮转的方式给每个任务分配一定的执行时间,然后把当前任务状态保存下来,接着加载下一任务的状态并执行,它是一个状态保存与加载的过程。

    一般线程调度模式分为两种——抢占式调度和协同式调度。

    抢占式调度指的是每条线程执行的时间、线程的切换都由系统控制,线程的切换不由线程本身决定,系统控制指的是在系统某种运行机制下,可能每条线程都分同样的执行时间片,也可能是某些线程执行的时间片较长,甚至某些线程得不到执行的时间片。在这种机制下,一个线程的堵塞不会导致整个进程堵塞。

    协同式调度指某一线程执行完后主动通知系统切换到另一线程上执行,线程的执行时间由线程本身控制,这种模式就像接力赛一样,一个人跑完自己的路程就把接力棒交接给下一个人,下个人继续往下跑。线程的执行时间由线程本身控制,线程切换可以预知,不存在多线程同步问题,但它有一个致命弱点:如果一个线程编写有问题,运行到一半就一直堵塞,那么可能导致整个系统崩溃。

    这里写图片描述

    左边为抢占式线程调度,假如三条线程需要运行,处理器运行的路径是在线程一运行一个时间片后强制切换到线程二运行一个时间片,然后切到线程三,再回到线程一,如此循环直至三条线程都执行完。而协同式线程调度则不这样走,它会先将线程一执行完,线程一再通知线程二执行,线程二再通知线程三,直到线程三执行完。

    Java使用的是哪种线程调度模式?此问题涉及到JVM的实现,JVM规范中规定每个线程都有优先级,且优先级越高越优先执行,但优先级高并不代表能独自占用执行时间片,可能是优先级高得到越多的执行时间片,反之,优先级低的分到的执行时间少但不会分配不到执行时间。JVM的规范没有严格地给调度策略定义,一般Java使用的线程调度是抢占式调度,在JVM中体现为让可运行池中优先级高的线程拥有CPU使用权,如果可运行池中线程优先级一样则随机选择线程,但要注意的是实际上一个绝对时间点只有一个线程在运行(这里是相对于一个CPU来说),直到此线程进入非可运行状态或另一个具有更高优先级的线程进入可运行线程池,才会使之让出CPU的使用权。

    ————-推荐阅读————

    我的2017文章汇总——机器学习篇

    我的2017文章汇总——Java及中间件

    我的2017文章汇总——深度学习篇

    我的2017文章汇总——JDK源码篇

    我的2017文章汇总——自然语言处理篇

    我的2017文章汇总——Java并发篇


    跟我交流,向我提问:

    这里写图片描述

    公众号的菜单已分为“读书总结”、“分布式”、“机器学习”、“深度学习”、“NLP”、“Java深度”、“Java并发核心”、“JDK源码”、“Tomcat内核”等,可能有一款适合你的胃口。

    为什么写《Tomcat内核设计剖析》

    欢迎关注:

    这里写图片描述

    展开全文
  • java线程调度

    2019-01-12 17:03:54
    线程调度是指系统为线程分配处理器使用权的过程,主要调度方式有两种:分别是协同式线程调度和抢占式线程调度。 协同式调度: 线程的执行时间由线程本身来控制,线程把自己的工作执行完了之后,要主动通知系统切换...

    线程调度是指系统为线程分配处理器使用权的过程,主要调度方式有两种:分别是协同式线程调度和抢占式线程调度。

    协同式调度:

    线程的执行时间由线程本身来控制,线程把自己的工作执行完了之后,要主动通知系统切换到另外一个线程上。

    协同式多线程最大的好处就是实现简单,而且由于线程要把自己的事情干完之后才会线程切换,切换操作对线程自己是可知的,没有什么线程同步的问题。

    缺点是:线程执行时间不可控制,甚至如果一个线程编写有问题,一直不告知系统进行线程切换,会导致程序阻塞。

    抢占式调度:

    每个线程将由系统来分配执行时间,线程的切换不由线程本身来决定(java.yield()可以让出执行时间,但是要获取执行时间的话,线程本身是没什么办法的),在这种实现线程调度的方式下,线程的执行时间是系统可控的,也不会有一个线程导致整个进程阻塞的问题,java使用的线程调度方式就是抢占式调度。

    虽然java线程调度是由系统自动完成的,但是可以设置线程优先级,来“建议”系统给某些线程多分配或少分配一些时间。java一共设置了10个线程优先级,两个线程都是Ready时,优先级越高的越容易被系统选择执行,(并不是说优先级越高的线程就一定比优先级低的线程先执行)。

    线程状态:

    线程状态一个有5种:

    新建(New):创建后尚未启动的线程处于这种状态。

    运行(Runable):Runable包括了操作系统线程状态中的Running和Ready,也就是此状态的线程有可能正在执行,也有可能等待着cpu在为它分配执行时间。

    无限期等待(Waiting):处于这种状态的线程不会被分配cpu执行时间,他们要等待被其他线程显示的唤醒,以下方法会让线程进入无限期等待:

    (1)没有设置Timeout参数的Object.wait()方法。

    (2)没有设置Timeout参数的Thread.join()方法。

    (3)LockSupport.park() 方法

    限期等待(Timed Waiting):处于这种状态的线程也不会被分配cpu执行时间,不过无须等待被其他线程显示地唤醒,在一定时间之后它会被系统自动唤醒,以下方法会让线程进入限期等待状态:

    (1)Thread.sleep()方法

    (2)设置了Timeout参数的Object.wait()方法。

    (3)设置了Timeout参数的Thread.join()方法。

    (4)lockSupport.parkNanos()方法

    (5)lockSupport.parkUntil()方法

    阻塞(Blocked):线程被阻塞了,阻塞状态与等待状态的区别:阻塞状态在等待着获取一个排他锁,这个事件将在另外一个线程放弃这个锁的时候发生,而等待状态则是在等待一段时间,或者唤醒动作的发生。在程序等待进入同步区域的时候,线程会进入这种状态。

    结束(Terminated):已终止的线程状态,线程已结束执行。

     

    线程转换关系(不画图了,用箭头表示,蓝色表示经过的方法,改变线程状态):

                 New——(start())——>Running——(run()结束)——>Terminated

                Waiting——(notify()或notifyAll())——>Running——(wait())——>Waiting

                Running——(synchronized)——>Blocked————>Running

                Running——(sleep())——>Timed Waiting————>Running

    展开全文
  • Java线程调度

    2019-07-19 09:34:29
    休眠是指让当前线程暂停执行,从运行状态进入阻塞状态,将 CPU 资源让给其他线程的一种调度方式。 实例 线程合并 合并是指将指定的某个线程合并到当前线程中,将原本两个交替执行的线程改为顺序执行,即一个线程...
  • JAVA 线程调度

    2017-01-04 15:40:11
    Java的线程调度  
  • java线程调度的两种方式: 一 协同线程调度 1.线程自己工作执行完后,要主动通知系统切换到另一个线程上。 2.好处是实现简单,没有什么线程同步问题。 3.如果一个线程编写有问题,一直不告知系统进行线程切换...
  • 主要介绍了Java线程调度之线程休眠用法,较为详细分析了Java线程休眠功能与实现技巧,需要朋友可以参考下
  • Java线程调度ScheduledThreadPoolExecutor简单使用样例代码例子:package test; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class Test { ...
  • Java线程调度机制

    千次阅读 2019-06-25 11:54:50
    所有的Java虚拟机都有一个线程调度器,用来确定那个时刻运行那个线程。主要包含两种:抢占式线程调度器和协作式线程调度器。 1.抢占式线程调度,每个线程可能会有自己优先级,但是优先及并不意味着高优先级线程...
  • Java线程调度与线程优先级

    千次阅读 2018-07-08 16:19:17
    线程调度是指系统为线程分配处理器使用权的过程,主要调度方式有两种,分别是协同式线程调度和抢占式线程调度。 1.1 协同式线程调度 协同式线程调度线程的执行时间由线程本身控制。协同式线程调度,线程执行...
  • Java线程调度

    千次阅读 2018-09-28 11:32:28
    每个虚拟机都有一个线程调度器,确实在任何时刻运行哪个线程。有两种线程调度器: 1、抢占式(preemptive) 2、协作式(cooperative) ...与使用抢占式线程式调度虚拟机相比,使用协作式线程调度器...
  • java线程调度原则

    2018-02-19 15:35:00
    线程的调度采用占先原则,优先级越高的线程越优先执行.每个JAVA线程优先级有设置在常数1-10的范围,默认值是5.但优先级高并不代表能独自占用执行时间片,而是优先级越高得到越多的执行时间片,反之,优先级低的分到的...
  • java 线程 调度

    2017-01-07 22:25:02
    它的对象是用来表示线程的。 Thread需要任务,任务是实现过Runnable的实例。 Runnable这个接口只有一个方法。 run()是新线程所执行的第一项方法。 要把Runnable传给Thread的构造函数才能启动新的线程。
  • java 线程调度策略

    2015-08-27 18:10:44
    线程的状态与调度  1,线程的生命周期  线程从创建、运行到结束总是处于下面五个状态之一:新建状态、就绪状态、运行状态、阻塞状态及死亡状态。  1.新建状态(New): 当用new操作符创建一个线程时,...
  • Java线程调度算法

    2020-08-10 09:08:51
    在运行池中,会有多个处于就绪状态的线程在等待CPU,JAVA虚拟机的一项任务就是负责线程的调度,线程调度是指按照特定机制为多个线程分配CPU的使用权. 有两种调度模型:分时调度模型和抢占式调度模型。 ...
  • 一、线程调度之优先级 1、调整线程优先级:Java线程有优先级,优先级高的线程会获得较多的运行机会。 Java线程的优先级用整数表示,取值范围是1~10,Thread类有以下三个静态常量: static int MAX_PRIORITY ...
  • 线程调度方式 抢占式调度 抢占式调度指的是每条线程执行的时间、线程的切换都由系统控制,系统控制指的是在系统某种运行机制下,可能每条线程都分同样的执行时间片,也可能是某些线程执行的时间片较长,甚至某些...
  • Java线程线程调度

    千次阅读 2017-08-04 14:47:20
    线程调度Java线程的核心,只有好的调度,才能充分发挥系统的性能,提高程序的执行效率。 一、休眠  休眠的目的是使线程让出CPU的最简单做法,线程休眠的时候,会将CPU交给其他线程,以便轮换执行,休眠一定...
  • 一、线程的生命周期与工作状态 一个线程“创建—>工作—>死亡”的过程称为线程的生命周期。线程的生命周期共有五个状态: 新建(New)、可运行(Runnable)、运行...二、Java线程调度与优先级 Java...
  • java线程调度示例代码

    2013-05-22 17:44:21
    /**《线程调度》  * Join()方法特点  * 1.当前线程会被挂起,让join过来线程先执行  * 2.join进来线程,没有执行完毕,会一直阻塞当前线程  *  * 注意:main方法启动时,就会创建当前java程序...

空空如也

1 2 3 4 5 ... 20
收藏数 14,755
精华内容 5,902
关键字:

java线程调度

java 订阅