精华内容
下载资源
问答
  • Java线程状态转化

    2018-09-30 17:26:49
    先来一张线程状态转化图,然后我再慢慢解释: 在Java中线程的状态一共被分成6种: 初始态:NEW 创建一个Thread对象,但还未调用start()启动线程时,线程处于初始态。 运行态:RUNNABLE 在Java中,运行态包括...

    先来一张线程状态转化图,然后我再慢慢解释:

    在Java中线程的状态一共被分成6种:

    初始态:NEW

    创建一个Thread对象,但还未调用start()启动线程时,线程处于初始态。

    运行态:RUNNABLE

    在Java中,运行态包括就绪态 和 运行态。

    • 就绪态
      • 该状态下的线程已经获得执行所需的所有资源,只要CPU分配执行权就能运行。
      • 所有就绪态的线程存放在就绪队列中。
    • 运行态
      • 获得CPU执行权,正在执行的线程。
      • 由于一个CPU同一时刻只能执行一条线程,因此每个CPU每个时刻只有一条运行态的线程。

    阻塞态

    • 当一条正在执行的线程请求某一资源失败时,就会进入阻塞态。
    • 而在Java中,阻塞态专指请求锁失败时进入的状态。
    • 由一个阻塞队列存放所有阻塞态的线程。
    • 处于阻塞态的线程会不断请求资源,一旦请求成功,就会进入就绪队列,等待执行。

    PS:锁、IO、Socket等都资源。

    等待态

    • 当前线程中调用wait、join、park函数时,当前线程就会进入等待态。
    • 也有一个等待队列存放所有等待态的线程。
    • 线程处于等待态表示它需要等待其他线程的唤醒才能继续运行。
    • 进入等待态的线程会释放CPU执行权,并释放资源(如:锁)

    超时等待态

    • 当运行中的线程调用sleep(time)、wait、join、parkNanos、parkUntil时,就会进入该状态;
    • 它和等待态一样,并不是因为请求不到资源,而是主动进入,并且进入后能够自动唤醒,不需要其他线程唤醒;
    • 进入该状态后释放CPU执行权 和 占有的资源。
    • 与等待态的区别:到了超时时间后自动进入阻塞队列,开始竞争锁。

    终止态

    线程执行结束后的状态。

     

    注意:

    • wait()方法会释放CPU执行权 和 占有的锁。
    • sleep(long)方法仅释放CPU使用权,锁仍然占用;线程被放入超时等待队列,与yield相比,它会使线程较长时间得不到运行。
    • yield()方法仅释放CPU执行权,锁仍然占用,线程会被放入就绪队列,会在短时间内再次执行。
    • wait和notify必须配套使用,即必须使用同一把锁调用;
    • wait和notify必须放在一个同步块中
    • 调用wait和notify的对象必须是他们所处同步块的锁对象。(不然报错IllegalMonitorStateException)

    转自:https://www.zhihu.com/question/27654579/answer/252912242 

    有资源有执行权:运行态
    有资源无执行权:就绪态
    无资源无执行权:阻塞态(会一直请求资源)
    主动释放资源和执行权,不设置超时时间,需要被唤醒:等待态
    主动释放资源和执行权,设置超时时间,能自动唤醒:超时等待态

    --------------------------------------------------------------------------------------

    从上面的例子中,我们看到了线程状态有BLOCKED,WAITING,TIMED_WAITING。 实际上线程状态有如下几种

    线程状态

    1. 新建状态(New):新创建了一个线程对象。
    2. 就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
    3. 运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
    4. 阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
    (一)、WAITING (on object monitor) 等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
    (二)、BLOCKED (on object monitor) 同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。区分同步阻塞和等待阻塞也可以看锁的特征,例如同步阻塞锁的特征是waiting for monitor, 等待阻塞锁的特征是object.wait()
    (三)、TIMED_WAITING(sleeping) 其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
    5. 死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

    原文链接:https://blog.csdn.net/T1DMzks/article/details/82719998

     

    展开全文
  • 一、背景 本文讲得内容比较简单,多线程大家接触很多,但是真正理解到位可能需要一点时间,尤其对新手来说。 本文顺便梳理一下多线程的知识,以两个简单的小...二、Java线程状态 线程共包括以下5种状态。 1.新...

    一、背景

    本文讲得内容比较简单,多线程大家接触很多,但是真正理解到位可能需要一点时间,尤其对新手来说。

    本文顺便梳理一下多线程的知识,以两个简单的小例子,谈谈自己的理解。

    视频有个别讲得不对的地方,欢迎批评指正,整理的是个人理解,仅供参考:

    https://www.bilibili.com/video/av54009506/

    二、Java线程状态

    线程共包括以下5种状态。
    1. 新建状态(New)         : 线程对象被创建后,就进入了新建状态。例如,Thread thread = new Thread()。
    2. 就绪状态(Runnable): 也被称为“可执行状态”。线程对象被创建后,其它线程调用了该对象的start()方法,从而来启动该线程。例如,thread.start()。处于就绪状态的线程,随时可能被CPU调度执行。
    3. 运行状态(Running) : 线程获取CPU权限进行执行。需要注意的是,线程只能从就绪状态进入到运行状态。
    4. 阻塞状态(Blocked)  : 阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
        (01) 等待阻塞 -- 通过调用线程的wait()方法,让线程等待某工作的完成。
        (02) 同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态。
        (03) 其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
    5. 死亡状态(Dead)    : 线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

    三、示例

    3.1 单线程

    package com.chujianyun.common.thread.safe;
    
    import org.apache.commons.collections.CollectionUtils;
    
    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.List;
    
    public class SafeDemo2 {
    
        public static void main(String[] args) throws InterruptedException {
    
            List<String> list = new LinkedList<>();
            list.add("tomcat");
    
            // 遍历元素
            Iterator<String> iterable = list.iterator();
            if (iterable.hasNext()) {
                System.out.println(iterable.next());
            }
    
            Thread.sleep(200);
    
            // 移除元素
            if (CollectionUtils.isNotEmpty(list)) {
                System.out.println("删除元素");
                list.remove(0);
            }
    
        }
    
    }
    

    单线程顺序执行

    主线程从上往下执行,先打印tomcat然后sleep阻塞200毫秒,进入就绪状态,获取CPU继续执行移除元素部分代码,然后主线程结束/死亡。

    3.2 多线程

    多线程,对于每个线程自己的视角看自己的任务,都是顺序执行的。

    但是整体的视角则可能是穿插进行的。

    在没有作同步处理的3个线程,分别打印A B C。每个线程的视角都是顺序打印自己的字符串。但是整体视角是交替打印。

    下面是和单线程类似的一个例子。

    package com.chujianyun.common.thread.safe;
    
    import java.util.Iterator;
    import java.util.List;
    
    public class MyThread1 extends Thread {
        private List<String> list;
    
        public MyThread1(List<String> list) {
            this.list = list;
        }
    
        @Override
        public void run() {
    
            Iterator<String> iterable = list.iterator();
            if (iterable.hasNext()) {
                System.out.println(iterable.next());
            }
        }
    }
    

     

    package com.chujianyun.common.thread.safe;
    
    import org.apache.commons.collections.CollectionUtils;
    
    import java.util.List;
    
    public class MyThread2 extends Thread {
        private List<String> list;
    
        public MyThread2(List<String> list) {
            this.list = list;
        }
    
        @Override
        public void run() {
    
            if (CollectionUtils.isNotEmpty(list)) {
                System.out.println("删除元素");
                list.remove(0);
            }
        }
    }
    

     

    package com.chujianyun.common.thread.safe;
    
    import java.util.LinkedList;
    import java.util.List;
    
    public class SafeDemo {
    
        public static void main(String[] args) throws InterruptedException {
    
            List<String> list = new LinkedList<>();
            list.add("tomcat");
    
            // 遍历元素
            MyThread1 myThread1 = new MyThread1(list);
            myThread1.start();
    
            Thread.sleep(200);
    
            // 移除元素
            MyThread2 myThread2 = new MyThread2(list);
            myThread2.start();
        }
    
    }
    

    运行,输出和上面的结果类似

     

    分析:

    三个线程,主线程(m),子线程1(t1),子线程2(t2).

     

    主线程顺序执行,创建t1,t1 start后进入就绪状态,获取CPU则直接运行(启动比t2早)。

    主线程sleep 200ms,然后进入就绪状态然后获取CPU执行,

    创建t2,t2 start 后进入就绪状态,如果获取CPU则直接运行(t2启动晚)。

    主线程结束。

    加入t1任务时长为1小时,t2运行时长为1分钟。则主线程先结束,其次t2,最后t1结束。

     

    下面讨论断点的情况:

    主线程顺序执行,创建子线程1,并启动子线程1,子线程1start后进入就绪状态,主线程sleep.

    t1获取CUP,执行,然后被断点断住。

    主线程sleep 200毫秒后继续到就绪状态,然后获取CUP继续执行,创建并启动t2。

    假设t2运行10ms,已经移除了List中元素。

    然后t1中断点的地方检查并发修改,抛并发修改异常

     

    另外注意调试多线程代码的时候

    断点右键选择Thread,否则其他线程会等待,没有想要的并发效果。

     

    具体演示和讲解参见视频。

    四、总结

    工作中可能用线程池更多一些,线程池的参数非常重要,这一块可以另外去学习了解。

    但是线程的状态和转换,线程执行的顺序也非常重要。

    遇到线程安全问题,如果没有足够扎实的基础知识,可能很难快速定位并排查。

    当遇到潜在的风险时,也很难有敏感度去提前发现。

    本文的讲解具体参见配套视频。

     

    因此多线程共享变量时特别要注意线程安全问题,使用线程安全的集合类,尽量避免共享,使用无”副作用“的函数。

     

    五、其他参考

    另外多线程这一块推荐看

    《深入理解Java虚拟机》、《Java并发编程实战》、《Java并发编程的艺术》、《 Java多线程编程核心技术

    另外强烈推荐图解Java多线程设计模式 》配图极大的帮助读者理解多线程,而且设计模式也非常经典。

    《阿里巴巴Java编程规范》关于线程安全问题的章节。

     

    最后附上本文博客关于线程池的相关文章:

    《Java ThreadPoolExecutor的拒绝策略》

    https://blog.csdn.net/w605283073/article/details/89930154

    《Java ThreadPoolExecutor的拒绝策略CallerRunsPolicy的一个潜在的大坑》

    https://blog.csdn.net/w605283073/article/details/89930497

    如果觉得本文对你有帮助,欢迎点赞,欢迎关注我,如果有补充欢迎评论交流,我将努力创作更多更好的文章。

     

     

    展开全文
  • 线程状态图说明:线程共包括以下5种状态。1.新建状态(New): 线程对象被创建后,就进入了新建状态。例如,Thread thread = new Thread()。2.就绪状态(Runnable): 也被称为“可执行状态”。线程对象被创建后,其它线程...

    线程状态图

    e42edf8b13f80e8491a3dcd2de46038e.png

    说明:

    线程共包括以下5种状态。

    1. 新建状态(New): 线程对象被创建后,就进入了新建状态。例如,Thread thread = new Thread()。

    2. 就绪状态(Runnable): 也被称为“可执行状态”。线程对象被创建后,其它线程调用了该对象的start()方法,从而来启动该线程。例如,thread.start()。处于就绪状态的线程,随时可能被CPU调度执行。

    3. 运行状态(Running) : 线程获取CPU权限进行执行。需要注意的是,线程只能从就绪状态进入到运行状态。

    4. 阻塞状态(Blocked) : 阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:

    (01) 等待阻塞 -- 通过调用线程的wait()方法,让线程等待某工作的完成。

    (02) 同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态。

    (03) 其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

    5. 死亡状态(Dead)    : 线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

    1. wait(), notify(), notifyAll()等方法介绍

    在Object.java中,定义了wait(), notify()和notifyAll()等接口。wait()的作用是让当前线程进入等待状态,同时,wait()也会让当前线程释放它所持有的锁。而notify()和notifyAll()的作用,则是唤醒当前对象上的等待线程;notify()是唤醒单个线程,而notifyAll()是唤醒所有的线程。

    Object类中关于等待/唤醒的API详细信息如下:

    notify()-- 唤醒在此对象监视器上等待的单个线程。

    notifyAll()  -- 唤醒在此对象监视器上等待的所有线程。

    wait()                               -- 让当前线程处于“等待(阻塞)状态”,“直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法”,当前线程被唤醒(进入“就绪状态”)。

    wait(long timeout)                -- 让当前线程处于“等待(阻塞)状态”,“直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量”,当前线程被唤醒(进入“就绪状态”)。

    wait(long timeout, int nanos)-- 让当前线程处于“等待(阻塞)状态”,“直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量”,当前线程被唤醒(进入“就绪状态”)。

    2. 为什么notify(), wait()等函数定义在Object中,而不是Thread中

    Object中的wait(), notify()等函数,和synchronized一样,会对“对象的同步锁”进行操作。

    wait()会使“当前线程”等待,因为线程进入等待状态,所以线程应该释放它锁持有的“同步锁”,否则其它线程获取不到该“同步锁”而无法运行!

    OK,线程调用wait()之后,会释放它锁持有的“同步锁”;而且,根据前面的介绍,我们知道:等待线程可以被notify()或notifyAll()唤醒。现在,请思考一个问题:notify()是依据什么唤醒等待线程的?或者说,wait()等待线程和notify()之间是通过什么关联起来的?答案是:依据“对象的同步锁”。

    负责唤醒等待线程的那个线程(我们称为“唤醒线程”),它只有在获取“该对象的同步锁”(这里的同步锁必须和等待线程的同步锁是同一个),并且调用notify()或notifyAll()方法之后,才能唤醒等待线程。虽然,等待线程被唤醒;但是,它不能立刻执行,因为唤醒线程还持有“该对象的同步锁”。必须等到唤醒线程释放了“对象的同步锁”之后,等待线程才能获取到“对象的同步锁”进而继续运行。

    总之,notify(), wait()依赖于“同步锁”,而“同步锁”是对象锁持有,并且每个对象有且仅有一个!这就是为什么notify(), wait()等函数定义在Object类,而不是Thread类中的原因。

    3. yield()介绍

    yield()的作用是让步。它能让当前线程由“运行状态”进入到“就绪状态”,从而让其它具有相同优先级的等待线程获取执行权;但是,并不能保证在当前线程调用yield()之后,其它具有相同优先级的线程就一定能获得执行权;也有可能是当前线程又进入到“运行状态”继续运行!

    4. yield() 与 wait()的比较

    我们知道,wait()的作用是让当前线程由“运行状态”进入“等待(阻塞)状态”的同时,也会释放同步锁。而yield()的作用是让步,它也会让当前线程离开“运行状态”。它们的区别是:

    (01) wait()是让线程由“运行状态”进入到“等待(阻塞)状态”,而不yield()是让线程由“运行状态”进入到“就绪状态”。

    (02) wait()是会线程释放它所持有对象的同步锁,而yield()方法不会释放锁。

    //YieldLockTest.java 的源码

    public classYieldLockTest{private static Object obj = newObject();public static voidmain(String[] args){

    ThreadA t1= new ThreadA("t1");

    ThreadA t2= new ThreadA("t2");

    t1.start();

    t2.start();

    }static class ThreadA extendsThread{publicThreadA(String name){super(name);

    }public voidrun(){//获取obj对象的同步锁

    synchronized(obj) {for(int i=0; i <10; i++){

    System.out.printf("%s [%d]:%d\n", this.getName(), this.getPriority(), i);//i整除4时,调用yield

    if (i%4 == 0)

    Thread.yield();

    }

    }

    }

    }

    }

    (某一次)运行结果:

    t1 [5]:0t1 [5]:1t1 [5]:2t1 [5]:3t1 [5]:4t1 [5]:5t1 [5]:6t1 [5]:7t1 [5]:8t1 [5]:9t2 [5]:0t2 [5]:1t2 [5]:2t2 [5]:3t2 [5]:4t2 [5]:5t2 [5]:6t2 [5]:7t2 [5]:8t2 [5]:9

    结果说明:

    主线程main中启动了两个线程t1和t2。t1和t2在run()会引用同一个对象的同步锁,即synchronized(obj)。在t1运行过程中,虽然它会调用Thread.yield();但是,t2是不会获取cpu执行权的。因为,t1并没有释放“obj所持有的同步锁”!

    5. sleep()介绍

    sleep() 定义在Thread.java中。

    sleep() 的作用是让当前线程休眠,即当前线程会从“运行状态”进入到“休眠(阻塞)状态”。sleep()会指定休眠时间,线程休眠的时间会大于/等于该休眠时间;在线程重新被唤醒时,它会由“阻塞状态”变成“就绪状态”,从而等待cpu的调度执行。

    6. sleep() 与 wait()的比较

    我们知道,wait()的作用是让当前线程由“运行状态”进入“等待(阻塞)状态”的同时,也会释放同步锁。而sleep()的作用是也是让当前线程由“运行状态”进入到“休眠(阻塞)状态”。

    但是,wait()会释放对象的同步锁,而sleep()则不会释放锁。

    下面通过示例演示sleep()是不会释放锁的。

    //SleepLockTest.java的源码

    public classSleepLockTest{private static Object obj = newObject();public static voidmain(String[] args){

    ThreadA t1= new ThreadA("t1");

    ThreadA t2= new ThreadA("t2");

    t1.start();

    t2.start();

    }static class ThreadA extendsThread{publicThreadA(String name){super(name);

    }public voidrun(){//获取obj对象的同步锁

    synchronized(obj) {try{for(int i=0; i <10; i++){

    System.out.printf("%s: %d\n", this.getName(), i);//i能被4整除时,休眠100毫秒

    if (i%4 == 0)

    Thread.sleep(100);

    }

    }catch(InterruptedException e) {

    e.printStackTrace();

    }

    }

    }

    }

    }

    主线程main中启动了两个线程t1和t2。t1和t2在run()会引用同一个对象的同步锁,即synchronized(obj)。在t1运行过程中,虽然它会调用Thread.sleep(100);但是,t2是不会获取cpu执行权的。因为,t1并没有释放“obj所持有的同步锁”!

    注意,若我们注释掉synchronized (obj)后再次执行该程序,t1和t2是可以相互切换的。

    展开全文
  • JAVA 线程状态转化

    2019-06-07 22:32:47
    文章目录线程状态图说明:线程共包括以下5种状态。1. wait(), notify(), notifyAll()等方法介绍2. 为什么notify(), wait()等函数定义在Object中,而不是Thread中3. yield()介绍4. yield() 与 wait()的比较 线程状态...

    线程状态图

    在这里插入图片描述

    说明:

    线程共包括以下5种状态。

    1. 新建状态(New) : 线程对象被创建后,就进入了新建状态。例如,Thread thread = new Thread()。
    2. 就绪状态(Runnable): 也被称为“可执行状态”。线程对象被创建后,其它线程调用了该对象的start()方法,从而来启动该线程。例如,thread.start()。处于就绪状态的线程,随时可能被CPU调度执行。
    3. 运行状态(Running) : 线程获取CPU权限进行执行。需要注意的是,线程只能从就绪状态进入到运行状态。
    4. 阻塞状态(Blocked) : 阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
      (01) 等待阻塞 – 通过调用线程的wait()方法,让线程等待某工作的完成。
      (02) 同步阻塞 – 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态。
      (03) 其他阻塞 – 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
    5. 死亡状态(Dead) : 线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

    1. wait(), notify(), notifyAll()等方法介绍

    在Object.java中,定义了wait(), notify()和notifyAll()等接口。wait()的作用是让当前线程进入等待状态,同时,wait()也会让当前线程释放它所持有的锁。而notify()和notifyAll()的作用,则是唤醒当前对象上的等待线程;notify()是唤醒单个线程,而notifyAll()是唤醒所有的线程。

    Object类中关于等待/唤醒的API详细信息如下:

    notify() – 唤醒在此对象监视器上等待的单个线程。
    notifyAll() – 唤醒在此对象监视器上等待的所有线程。
    wait() – 让当前线程处于“等待(阻塞)状态”,“直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法”,当前线程被唤醒(进入“就绪状态”)。
    wait(long timeout) – 让当前线程处于“等待(阻塞)状态”,“直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量”,当前线程被唤醒(进入“就绪状态”)。
    wait(long timeout, int nanos) – 让当前线程处于“等待(阻塞)状态”,“直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量”,当前线程被唤醒(进入“就绪状态”)。


    2. 为什么notify(), wait()等函数定义在Object中,而不是Thread中

    Object中的wait(), notify()等函数,和synchronized一样,会对“对象的同步锁”进行操作。

    wait()会使“当前线程”等待,因为线程进入等待状态,所以线程应该释放它锁持有的“同步锁”,否则其它线程获取不到该“同步锁”而无法运行!
    OK,线程调用wait()之后,会释放它锁持有的“同步锁”;而且,根据前面的介绍,我们知道:等待线程可以被notify()或notifyAll()唤醒。现在,请思考一个问题:notify()是依据什么唤醒等待线程的?或者说,wait()等待线程和notify()之间是通过什么关联起来的?答案是:依据“对象的同步锁”。

    负责唤醒等待线程的那个线程(我们称为“唤醒线程”),它只有在获取“该对象的同步锁”(这里的同步锁必须和等待线程的同步锁是同一个),并且调用notify()或notifyAll()方法之后,才能唤醒等待线程。虽然,等待线程被唤醒;但是,它不能立刻执行,因为唤醒线程还持有“该对象的同步锁”。必须等到唤醒线程释放了“对象的同步锁”之后,等待线程才能获取到“对象的同步锁”进而继续运行。

    总之,notify(), wait()依赖于“同步锁”,而“同步锁”是对象锁持有,并且每个对象有且仅有一个!这就是为什么notify(), wait()等函数定义在Object类,而不是Thread类中的原因。


    3. yield()介绍

    yield()的作用是让步。它能让当前线程由“运行状态”进入到“就绪状态”,从而让其它具有相同优先级的等待线程获取执行权;但是,并不能保证在当前线程调用yield()之后,其它具有相同优先级的线程就一定能获得执行权;也有可能是当前线程又进入到“运行状态”继续运行!


    4. yield() 与 wait()的比较

    我们知道,wait()的作用是让当前线程由“运行状态”进入“等待(阻塞)状态”的同时,也会释放同步锁。而yield()的作用是让步,它也会让当前线程离开“运行状态”。它们的区别是:
    (01) wait()是让线程由“运行状态”进入到“等待(阻塞)状态”,而不yield()是让线程由“运行状态”进入到“就绪状态”。
    (02) wait()是会线程释放它所持有对象的同步锁,而yield()方法不会释放锁。

    展开全文
  • java线程状态转化

    2018-03-02 13:48:02
    线程状态图说明:线程共包括以下5种状态。1. 新建状态(New) : 线程对象被创建后,就进入了新建状态。例如,Thread thread = new Thread()。2. 就绪状态(Runnable): 也被称为“可执行状态”。线程对象被创建后,...
  • Java 线程状态转化

    2019-04-22 15:01:22
    1. wait(), notify(), notifyAll()等方法介绍 2. 为什么notify(), wait()等函数定义在Object中,而不是Thread中 3. yield()介绍 ...线程状态图 说明: 线程共包括以下5种状态。 1.新建状态(N...
  • 目录Java线程的六种状态转化一、新建状态(NEW)二、运行状态(RUNNABLE)就绪状态(READY)运行状态(RUNNING)三、阻塞状态(BLOCKED)四、等待状态(WAITING)运行->等待等待->就绪五、超时等待状态(TIMED_WAITING)...
  • 4 Java线程的状态及主要转化方法4.1 操作系统中的线程状态转换首先我们来看看操作系统中的线程状态转换。在现在的操作系统中,线程是被视为轻量级进程的,所以操作系统线程的状态其实和操作系统进程的状态是一致的。...
  • 线程状态图 说明: 线程共包括以下5种状态。 新建状态(New) : 线程对象被创建后,就进入了新建状态。例如,Thread thread = new Thread()。 就绪状态(Runnable): 也被称为“可执行状态”。线程对象被创建后,...
  • 线程状态 和进程意义。线程从启动到终止一种由5个状态。分别时创建状态,就绪状态,运行状态,阻塞状态和终止状态状态转换常用方法 创建状态-&amp;gt;(start()方法)-&amp;gt;就绪状态 就绪状态-...
  • 一、线程的5种状态 众所周知,Java线程状态有5种,分别对应上图中五种不同颜色,下面对这5种状态及状态间的转化做相应的解释: 1. 初始化状态:新建一个线程对象 2. 可运行状态:其他线程调用了该线程对象的start...
  • 多线程概述及创建方式Java:线程的六种状态及转化关于线程的生命周期,网上书上说法不一,...线程状态解释NEW尚未启动的线程状态,即线程创建,还未调用start方法RUNNABLE就绪状态(调用start,等待调度)+正在运行BLO...
  • 关于线程的生命周期,网上书上说法不一,难以统一,本篇做一个总结:java.lang.Thread.State枚举类中定义了六种线程状态,可以调用线程Thread中的getState()方法获取当前线程状态。下图源自《Java并发编程艺术》...
  • 搜索热词多线程概述及创建方式Java:线程的六种状态及转化关于线程的生命周期,网上书上说法不一,难以统一,...线程状态解释NEW@H_301_73@尚未启动的线程状态,即线程创建,还未调用start方法@H_301_73@RUNNABLE@H...
  • Java线程的状态及主要转化方法 1 操作系统中的线程状态转换 首先我们来看看操作系统中的线程状态转换。 在现在的操作系统中,线程是被视为轻量级进程的,所以操作系统线程的状态其实和操作系统进程的状态是一致的。...
  • Java线程状态

    千次阅读 2014-11-29 19:03:17
    线程跟人类一样拥有自己的生命周期,一条线程从创建到执行完毕的过程即是线程的生命周期,此过程可能在不同时刻处于不同的状态,线程状态正是这小节的主题,线程到底有多少种状态?不同状态之间是如何转化的? 对于...
  • 操作系统中的线程状态转换 首先我们来看看操作系统中的线程状态转换。 在现在的操作系统中,线程是被视为轻量级进程的,所以操作系统线程的状态其实和操作系统进程的状态...Java线程的6个状态 // Thread.State 源码 p
  • Java线程6种状态: 1.new(初始化):start()方法转runnable 2.runnable(可执行/执行): 等待synchronized 的隐式锁时转blocked 3.blocked(阻塞): 当等待的线程获得 synchronized 隐式锁时,就又会从 BLOCKED 转换到 ...
  • 线程状态转化图: 说明: 线程总共包括以下5种状态。 1、新状态New:该状态也叫新建状态,当线程对象被创建后,线程就进入了新建状态。例如:Thread thread = new Thread();。 2、就绪状态Runnable:该状态也...
  • situation1/2使得线程状态从RUNNING转化为WAITING/TIMED_WAITING 还有一种情况就是IO阻塞,例子如下: import java.util.concurrent.ArrayBlockingQueue; public class c { private static ArrayBlockingQueue
  • 目录 目录 一、线程的5种状态 ...众所周知,Java线程状态有5种,分别对应上图中五种不同颜色,下面对这5种状态及状态间的转化做相应的解释: 1. 初始化状态:新建一个线程对象 2. ...
  • 一、众所周知,Java线程状态有5种,分别对应上图中五种不同颜色,下面对这5种状态及状态间的转化做相应的解释:1.初始化状态:新建一个线程对象2.可运行状态:其他线程调用了该线程对象的start()方法。该状态的...
  • Java线程状态以及状态转化 NEW 创建线程 TIMED_WAITING 线程无限等待或者超时等待 WATING 线程等待 RUNNABLE 线程处于运行态(RUNNING)或者就绪态(READY) TERMINATED 终止 BLOCKED 锁 线程阻塞 [外链图片转存...
  • Java线程状态

    2018-06-08 08:33:33
    不同状态之间是如何转化的? 对于线程状态的分类并没有严格的规定,只要能正确表示状态即可,如图,先看其中一种状态分类,一个线程从创建到死亡可能会经历若干个状态,但在任意一个时间点线程只能处于其中一种...
  • java线程状态

    2018-06-29 15:45:11
    转化过程是一个单向过程,可运行状态:在此状态下,线程在等待分配cpu时间片,线程根据是否被分配到了时间片在运行状态可运行状态转化终止状态:在线程执行完了run 方法中的代码后线程进入...
  • Java多线程:线程状态

    2020-06-10 19:43:36
    # 面试题Java线程有哪几种状态线程的生命周期。每个状态的含义。状态之间的转化过程以及触发条件,图示。# 线程有哪几种状态Java docimage.pngNew (刚创建出线程实...

空空如也

空空如也

1 2 3 4 5 ... 10
收藏数 190
精华内容 76
关键字:

java线程状态转化

java 订阅