Java并发之线程状态及创建(1)

一、状态解读

Java线程状态迁移.png

1、New 初始状态

创建线程后,未运行

2、Runnable 可运行状态

可能在运行也可能在等待CPU时间片
同时也包含了操作系统线程的Ready 和 Running

着重说一下Thread.yield()
Thread.yield()方法作用是:暂停当前正在执行的线程对象(及放弃当前拥有的cup资源),并执行其他线程。

yield()做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会。因此,使用yield()的
目的是让相同优先级的线程之间能适当的轮转执行。但是,实际中无法保证yield()达到让步目的,因为让步的线程还有可能被
线程调度程序再次选中。

结论:yield()从未导致线程转到等待/睡眠/阻塞状态。在大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果。

3、Blocked 阻塞

等待获取一个Synchronized锁,如果抢占到锁就会离开此状态。

4、Waiting 等待

等待其它线程显示的唤醒,否则一直等待下去。

进入 退出
没有设置Time out参数的Object.wait() Object.notify() 或 Object.notifyAll()
没有设置Time out参数的Thread.join() 被调用的线程执行完毕
LockSupport.park() LockSupport.unpark(Thread thread)

5、Timed Waiting 超时等待

进入 退出
Object.wait(Long) Object.notify() 或 Object.notifyAll()
Thread.join(Long) 超时退出 或 被调用的线程执行完毕
Thread.sleep(Long) 超时退出
LockSupport.parkNanos(Long) LockSupport.unpark()
LockSupport.parkUntil(Long) LockSupport.unpark()

6、Terminated 终止状态

当线程的run()方法执行完毕或者主线程的main()方法完毕,就终止了,也许在这一刻,该线程还是存活的,但是它就要被终止了。

在一个终止的线程上调用start()方法会抛出异常java.lang.IllegalThreadStateException,线程一旦被终止,就无法再次运行。

二、创建

Java线程的创建分为四种方式:

1)继承Tread类

    public class MyThread extends Thread {
        public void run() {
            System.out.println("我是继承于Thread的线程类");
        }
    }
    
    ==================分割线====================

    @Slf4j
    public class JunitTest {
        @Test
        public void test() throws InterruptedException {
            MyThread thread = new MyThread();

            thread.start();
    
            Thread.sleep(3000);
        }
    }

继承Thread类,重写其run()方法,然后通过start()方法调用即可,如果直接调用run()方法,那么就相当于调用同步方法,只有调用start()才是启动线程的正解。

2)实现Runnable接口

    public class MyThread implements Runnable {
        @Override
        public void run() {
            System.out.println("我是实现Runnable接口的线程类");
        }
    }

    ==================分割线====================

    @Slf4j
    public class JunitTest {
        @Test
        public void test() throws InterruptedException {
            MyThread myThread = new MyThread();
            
            // 传入MyThread实例
            Thread thread = new Thread(myThread);
    
            thread.start();
            
            Thread.sleep(3000);
        }
    }

实现Runnable接口,重写其run()方法。
限于第一种方式,受继承的限制,第二种比第一种方式能好一些

3)实现Callable接口

    public class MyThread implements Callable<String> {
    
        @Override
        public String call() throws Exception {
            System.out.println("我是实现Callable接口的线程类");
            return "ok";
        }
    }

    ==================分割线====================

    @Test
    public void test() throws Exception {
        Callable<String> callable = new MyThread();
    
        FutureTask<String> futureTask = new FutureTask<>(callable);
    
        Thread thread = new Thread(futureTask);
    
        thread.start();
    
        Thread.sleep(3000);
    }

覆写call()方法,且支持返回值!

4)通过线程池

可以通过Executors来创建几种不同类型的线程池。Executors是一个线程池工厂,提供了创建线程池的很多方法。

1)SingleThreadPoolExecutor

只有一个线程的线程池。多个任务被提交到该线程池,先被缓存到队列(队列长度为Integer.MAX_VALUE),按照FIFO先进先出的原则进行任务处理。

2)FixedThreadPool

固定大小的线程池,内部存储的线程数量是固定的,和上面的处理流程极为类似,但是该线程池可以处理多个任务,多个任务被提交到线程池,按照以下过程进行处理:

1)如果线程的数量未达到设置的数量,线程池会创建线程来处理任务。

2)如果线程池里的线程数量达到了设置的数量,则取出空闲的线程执行任务

3)如果没有空闲线程,则将任务缓存到队列(队列长度为Integer.MAX_VALUE),当有空闲线程时,按照FIFO的原则进行任务处理

严格按照 1 -> 2 -> 3的过程进行处理。

3)CachedThreadPool

创建带缓存的线程池,这种线程池可以回收空闲线程,当任务到达后,直接使用空闲线程,没有空闲线程时,新建线程。线程池核心长度为0,最大长度为Integer.MAX_VALUE
用户可以传入线程池的核心线程数(最小线程数),最大线程数量,保持时间,时间单位,阻塞队列这些参数,最大线程数设置为jvm可用的cpu数为宜。

4)ScheduledThreadPool

一个可定期或者延时执行任务的线程池

5) WorkStealingPool

创建拥有足够线程数的线程池来维持相应的并行级别,通过使用队列来减少竞争,默认为CPU的数量。它会通过工作窃取的方式,使得多核CPU不会闲置,总会有活着的线程让CPU去运行。

所谓工作窃取,指的是闲置的线程去处理本不属于它的任务。

在实际项目里,我们很少成规模的手动创建线程,一般都是使用线程池(池技术)将线程的创建、销毁、保留及其它管理工作交给线程池,用户无需知道其内部细节,即可使用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342