偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Java多線程從創(chuàng)建開(kāi)始—?jiǎng)?chuàng)建和使用以及了解多線程的切換策略

開(kāi)發(fā) 前端
成員變量共同使用,如果不定義為static,則繼承Thread類(lèi)就是各自使用各自的,但是實(shí)現(xiàn)Runnable接口,只需要?jiǎng)?chuàng)建一次對(duì)象,成員變量也相當(dāng)于是共享的。

方式一:繼承Thread類(lèi)

  1. 繼承Thread類(lèi)
  2. 重寫(xiě)run方法,在run方法中添加想要線程執(zhí)行的內(nèi)容
  3. 創(chuàng)建繼承Thread類(lèi)的類(lèi)對(duì)象
  4. 調(diào)用start方法,一個(gè)對(duì)象只允許調(diào)用一次start方法,否則報(bào)錯(cuò)java.lang.IllegalThreadStateException
  5. 每一個(gè)對(duì)象調(diào)用一次start方法就是一個(gè)線程

注意事項(xiàng):

  1. 用戶(hù)手動(dòng)調(diào)用run()方法并不會(huì)啟動(dòng)線程,必須通過(guò)start()方法告訴JVM虛擬機(jī)使用run()方法啟動(dòng)線程
  2. 為什么要重寫(xiě)run方法呢? 因?yàn)閞un方法是用來(lái)封裝被線程執(zhí)行的代碼
  3. run()和start()方法的區(qū)別? run():封裝線程執(zhí)行的代碼,直接調(diào)用,相當(dāng)于普通方法的調(diào)用 start():?jiǎn)?dòng)線程,然后由JVM調(diào)用此線程的run()方法啟動(dòng)線程
public class MultithreadingTest extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("這是線程"+i+currentThread().getName());
        }
    }

    public static void main(String[] args) {
        MultithreadingTest mt=new MultithreadingTest();
        mt.start();//Exception in thread "main" java.lang.IllegalThreadStateException
        MultithreadingTest mt1=new MultithreadingTest();
        mt1.start();
        //mt.start();
    }
}

方式二:實(shí)現(xiàn)Runable接口

  1. 實(shí)現(xiàn)Runnable接口
  2. 重寫(xiě)run方法,在run方法中添加想要線程執(zhí)行的內(nèi)容
  3. 創(chuàng)建實(shí)現(xiàn)Runnable接口的類(lèi)對(duì)象
  4. 創(chuàng)建多個(gè)Thread實(shí)例對(duì)象,將實(shí)現(xiàn)了Runnable接口的實(shí)例對(duì)象放入Thread實(shí)例對(duì)象中
  5. 調(diào)用start方法,一個(gè)Thread實(shí)例對(duì)象只能調(diào)用一次start方法,否則報(bào)錯(cuò)java.lang.IllegalThreadStateException
  6. 每個(gè)Thread對(duì)象調(diào)用一次start方法就代表一個(gè)線程
class RunnableTest implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("這是Runnable線程"+i+"-->"+Thread.currentThread().getName());
        }
    }

    public static void main(String[] args) {
        RunnableTest rt=new RunnableTest();
        Thread t1=new Thread(rt,"t1");
        Thread t2=new Thread(rt,"t2");
        Thread t3=new Thread(rt,"t3");
        t1.start();
        t2.start();
        t3.start();
    }
}

方式三:實(shí)現(xiàn)Callable接口

  1. 實(shí)現(xiàn)Callable接口,需要返回值類(lèi)型,返回值為泛型類(lèi)型,如果沒(méi)有泛型則默認(rèn)為Object
  2. 重寫(xiě)call方法,需要拋出異常
  3. 創(chuàng)建繼承了Callable接口的類(lèi)對(duì)象
  4. 創(chuàng)建FutureTask對(duì)象,傳入繼承了Callable接口的類(lèi)對(duì)象
  5. new Thread(FutureTask的實(shí)例對(duì)象).start()
  6. 如果需要取call方法的返回值,則使用get方法
class CallableTest implements Callable {
    @Override
    public Object call() throws Exception {
        int num=0;
        for (int i = 1; i <= 100; i++) {
            if (i%2==0) {
                System.out.println(i);
                num += i;
            }
        }
        return num;
    }

    public static void main(String[] args) {
        CallableTest ct=new CallableTest();
        FutureTask ft=new FutureTask(ct);
        new Thread(ft).start();
        try {
            int i= (Integer) ft.get();
            System.out.println("總和為:"+i);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

方式四:線程池的方式

  1. 實(shí)現(xiàn)Callable接口,需要返回值類(lèi)型,返回值為泛型類(lèi)型,如果沒(méi)有泛型則默認(rèn)為Object
  2. 重寫(xiě)call方法,需要拋出異常
  3. 創(chuàng)建繼承了Callable接口的類(lèi)對(duì)象
  4. 創(chuàng)建執(zhí)行服務(wù)ExecutorService類(lèi)對(duì)象(創(chuàng)建線程池),并設(shè)定線程數(shù)
  5. 提交執(zhí)行服務(wù)es.submit(),提交數(shù)不可超過(guò)設(shè)定的線程數(shù),超過(guò)的線程數(shù)不生效關(guān)閉服務(wù)es.shutdownNow()
/**
* 線程池相關(guān)API:ExecutorService和Excutors
* ExcutorService:真正的線程池接口;常見(jiàn)的子類(lèi)ThreadPoolExcutor
*   1.void execute(Runnable command):執(zhí)行任務(wù)/命令,沒(méi)有返回值,一般用來(lái)執(zhí)行Runnable
*  2.<T>Future<T> submit(Callable<T> task):執(zhí)行任務(wù),有返回值,一般用來(lái)執(zhí)行Callable
*  3.void shutdown():關(guān)閉連接池
* Executors:工具類(lèi)、線程池的工廠類(lèi),用于創(chuàng)建并返回不同類(lèi)型的線程池
*  1.Executors.newCachedThreadPool():創(chuàng)建一個(gè)可根據(jù)需要?jiǎng)?chuàng)建新線程的線程池
*  2.Executors.newFixedThreadPool(n):創(chuàng)建一個(gè)可重用固定線程數(shù)的線程池
*  3.Executors.newSingleThreadExecutor():創(chuàng)建一個(gè)只有一個(gè)線程的線程池
*  4.Executors.newScheduledThreadPool(n):創(chuàng)建一個(gè)線程池,它可安排在給定延遲后運(yùn)行命令或定期地執(zhí)行
*/
class CallAbleTest implements Callable<Boolean>{
    @Override
    public Boolean call() throws Exception {
        for (int i = 0; i < 100; i++) {
            System.out.println("這是Callable線程"+i+"-->"+Thread.currentThread().getName());
        }
        return true;
    }

    public static void main(String[] args) {
        CallAbleTest ct=new CallAbleTest();

        //創(chuàng)建執(zhí)行服務(wù)
        ExecutorService es= Executors.newFixedThreadPool(3);
        //提交執(zhí)行
        Future<Boolean> f1=es.submit(ct);
        Future<Boolean> f2=es.submit(ct);
        Future<Boolean> f3=es.submit(ct);
        Future<Boolean> f4=es.submit(ct);
        //獲取結(jié)果
        try {
            boolean r1=f1.get();
            boolean r2=f2.get();
            boolean r3=f3.get();
            boolean r4=f4.get();
            System.out.println("r1 = " + r1+" r2 = " + r2+" r3 = " + r3+" r4="+r4);;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        //關(guān)閉服務(wù)
        es.shutdownNow();
    }
}

Thread和Runnable對(duì)比

重點(diǎn)說(shuō)明:

在開(kāi)發(fā)中Thread和Runnable優(yōu)先選擇實(shí)現(xiàn)Runnable接口

原因:

  1. 實(shí)現(xiàn)的方式?jīng)]有類(lèi)的單繼承的局限性
  2. 實(shí)現(xiàn)的方式更適合處理多個(gè)線程有共享數(shù)據(jù)的情況

舉例說(shuō)明:成員變量共同使用,如果不定義為static,則繼承Thread類(lèi)就是各自使用各自的,但是實(shí)現(xiàn)Runnable接口,只需要?jiǎng)?chuàng)建一次對(duì)象,成員變量也相當(dāng)于是共享的

實(shí)現(xiàn)Callable接口比Runnable強(qiáng)大 原因:

  1. call方法有返回值
  2. call方法可以?huà)伋霎惓2⒉东@(使用get方法)

線程池的創(chuàng)建重點(diǎn):

  1. 線程池的大小一般為服務(wù)器核數(shù)*2+有效磁盤(pán)數(shù)
  2. 線程池內(nèi)的線程可以頻繁使用,使用完了會(huì)歸還而不會(huì)銷(xiāo)毀(重復(fù)利用)
  3. 減少頻繁創(chuàng)建和銷(xiāo)毀消耗大量的時(shí)間(空間換時(shí)間)
  4. 線程池的設(shè)計(jì)可以便于管理,避免多用戶(hù)創(chuàng)建導(dǎo)致的宕機(jī)

出現(xiàn)線程安全問(wèn)題的原因: 當(dāng)多條語(yǔ)句在操作同一個(gè)線程共享數(shù)據(jù)時(shí),一個(gè)線程對(duì)多條語(yǔ)句只執(zhí)行了一部分,還沒(méi)有執(zhí)行完,另一個(gè)線程參與進(jìn)來(lái)執(zhí)行,導(dǎo)致共享數(shù)據(jù)錯(cuò)誤

解決辦法: 對(duì)多條操作共享數(shù)據(jù)的語(yǔ)句,只能讓一個(gè)線程都執(zhí)行完,在執(zhí)行過(guò)程中不允許其他線程參與執(zhí)行

多線程調(diào)度策略

  • 分時(shí)調(diào)度模型:

時(shí)間片策略:所有線程輪流使用CPU的使用權(quán),平均分配每個(gè)線程占用的CPU的時(shí)間片

優(yōu)先級(jí)調(diào)度策略:根據(jù)線程的優(yōu)先級(jí)來(lái)分配CPU資源,高優(yōu)先級(jí)的線程優(yōu)先執(zhí)行

同優(yōu)先級(jí)線程是先進(jìn)先出的隊(duì)列,使用時(shí)間片策略;不同優(yōu)先級(jí)線程采用優(yōu)先級(jí)調(diào)度策略

  • 搶占式調(diào)度模型:

對(duì)高優(yōu)先級(jí)的使用優(yōu)化調(diào)度的搶占式策略

搶占式策略:優(yōu)先讓優(yōu)先級(jí)高的線程使用CPU,如果線程的優(yōu)先級(jí)相同,那么會(huì)隨機(jī)選擇一個(gè),優(yōu)先級(jí)高的線程獲取CPU時(shí)間片相對(duì)多一些

  • 線程的優(yōu)先級(jí)等級(jí)

MAX_PRIORITY:10【最高優(yōu)先級(jí)】

MIN_PRIORITY:1【最低優(yōu)先級(jí)】

NORM_PRIORITY:5【默認(rèn)優(yōu)先級(jí)】

  • 優(yōu)先級(jí)的方法

getPriority():返回線程優(yōu)先值

setPriority(int newPriority):改變線程的優(yōu)先級(jí),數(shù)越大優(yōu)先級(jí)越高

  • 說(shuō)明:

線程創(chuàng)建時(shí),繼承父線程的優(yōu)先級(jí)

低優(yōu)先級(jí)只是獲得調(diào)度的概率低,并非一定是在高優(yōu)先級(jí)線程之后才被調(diào)用

對(duì)應(yīng)Windows線程優(yōu)先級(jí)

Java線程優(yōu)先級(jí)

Windows線程優(yōu)先級(jí)

1(Thread.MIN_PRIORITY)

THREAD_PRIORITY_LOWEST

2

THREAD_PRIORITY_LOWEST

3

THREAD_PRIORITY_BELOW_NORMAL

5(Thread.NORM_PRIORITY)

THREAD_PRIORITY_NORMAL

6

THREAD_PRIORITY_ABOVE_NORMAL

7

THREAD_PRIORITY_ABOVE_NORMAL

8

THREAD_PRIORITY_HIGHEST

9

THREAD_PRIORITY_HIGHEST

10(Thread.MAX_PRIORITY)

THREAD_PRIORITY_GRITICAL

優(yōu)先級(jí)的方法

  • getPriority():返回線程優(yōu)先值
  • setPriority(int newPriority):改變線程的優(yōu)先級(jí),數(shù)越大優(yōu)先級(jí)越高

說(shuō)明:

  • 線程創(chuàng)建時(shí),繼承父線程的優(yōu)先級(jí)
  • 低優(yōu)先級(jí)只是獲得調(diào)度的概率低,并非一定是在高優(yōu)先級(jí)線程之后才被調(diào)用
責(zé)任編輯:武曉燕 來(lái)源: 愛(ài)編程的杰尼龜
相關(guān)推薦

2023-06-06 08:17:52

多線程編程Thread類(lèi)

2010-03-10 08:54:49

Python多線程

2009-06-29 18:00:05

Java多線程Runnable接口創(chuàng)建線程

2010-03-15 17:56:23

Java多線程

2009-06-29 17:54:10

Java多線程Thread類(lèi)創(chuàng)建線程

2010-02-01 17:18:23

Python多線程環(huán)境

2021-02-25 15:58:46

C++線程編程開(kāi)發(fā)技術(shù)

2021-09-11 15:26:23

Java多線程線程池

2009-03-12 10:52:43

Java線程多線程

2016-11-10 16:30:22

Java多線程

2009-08-12 13:22:44

Singleton模式

2019-02-26 11:15:25

進(jìn)程多線程多進(jìn)程

2021-12-26 18:22:30

Java線程多線程

2009-06-29 17:49:47

Java多線程

2010-03-17 14:58:20

Java多線程

2011-06-16 10:38:13

Qt多線程編程

2009-06-29 18:08:51

Java多線程join方法

2011-07-01 11:18:50

Qt 多線程

2011-04-14 13:27:53

Synchronize多線程

2009-06-29 18:22:54

Java多線程從線程返回?cái)?shù)據(jù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)