真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

實現(xiàn)Java線程的方法有哪些

這篇文章主要介紹“實現(xiàn)Java線程的方法有哪些”,在日常操作中,相信很多人在實現(xiàn)Java線程的方法有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”實現(xiàn)Java線程的方法有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

成都創(chuàng)新互聯(lián)是一家專注于成都網(wǎng)站建設、成都做網(wǎng)站與策劃設計,京口網(wǎng)站建設哪家好?成都創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設10余年,網(wǎng)設計領域的專業(yè)建站公司;建站業(yè)務涵蓋:京口等地區(qū)。京口做網(wǎng)站價格咨詢:18982081108

搞懂兩件事: 為什么說本質(zhì)上只有一種實現(xiàn)線程的方式? 實現(xiàn) Runnable 接口究竟比繼承 Thread 類實現(xiàn)線程好在哪里?

一:常見的實現(xiàn)線程的方式

1:實現(xiàn)Runable接口

public class RunnableThread  implements Runnable{
    @Override
    public void run() {
        System.out.println("用實現(xiàn)Runnable接口實現(xiàn)線程");
    }
    public static void main(String[] args) {
        Thread thread=new Thread(new RunnableThread());
        thread.start();
    }
}

如代碼所示,首先通過 RunnableThread 類實現(xiàn) Runnable 接口,然后重寫 run() 方法,之后只需要把這個實現(xiàn)了 run() 方法的實例傳到 Thread 類中就可以實現(xiàn)多線程。

2:繼承Thread類

public class ExtendsThread extends Thread{
    @Override
    public void run() {
        System.out.println("用繼承Thread類實現(xiàn)線程");
    }
}

與第 1 種方式不同的是它沒有實現(xiàn)接口,而是繼承 Thread 類,并重寫了其中的 run() 方法。

3:線程池創(chuàng)建線程

下面是線程池中的源碼,來看看線程池是怎么實現(xiàn)線程的:

    /**
     * The default thread factory
     */
    static class DefaultThreadFactory implements ThreadFactory {
        private static final AtomicInteger poolNumber = new AtomicInteger(1);
        private final ThreadGroup group;
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix;

        DefaultThreadFactory() {
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() :
                                  Thread.currentThread().getThreadGroup();
            namePrefix = "pool-" +
                          poolNumber.getAndIncrement() +
                         "-thread-";
        }

        public Thread newThread(Runnable r) {
            Thread t = new Thread(group, r,
                                  namePrefix + threadNumber.getAndIncrement(),
                                  0);
            if (t.isDaemon())
                t.setDaemon(false);
            if (t.getPriority() != Thread.NORM_PRIORITY)
                t.setPriority(Thread.NORM_PRIORITY);
            return t;
        }
    }

對于線程池而言,本質(zhì)上是通過線程工廠創(chuàng)建線程的,默認采用 DefaultThreadFactory,它會給線程池創(chuàng)建的線程設置一些默認值,比如:線程的名字、是否是守護線程,以及線程的優(yōu)先級等。但是最終都是通過new Thread()創(chuàng)建線程的,只是參數(shù)多了些而已。

4:有返回值的 Callable 創(chuàng)建線程

public class CallableTask implements Callable {
    @Override
    public Integer call() throws Exception {
        return new Random().nextInt();
    }
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        Future future = executorService.submit(new CallableTask());
        System.out.println(future.get());
        System.out.println(future.isDone());
        System.out.println(future.isCancelled());
    }
}

Runnable 創(chuàng)建線程是無返回值的,而 Callable 和與之相關的 Future、FutureTask,它們可以把線程執(zhí)行的結(jié)果作為返回值返回,如代碼所示,實現(xiàn)了 Callable 接口,并且給它的泛型設置成 Integer,然后它會返回一個隨機數(shù)。

但是,無論是 Callable 還是 FutureTask,它們首先和 Runnable 一樣,都是一個任務,是需要被執(zhí)行的,而不是說它們本身就是線程。它們可以放到線程池中執(zhí)行,如代碼所示, submit() 方法把任務放到線程池中,并由線程池創(chuàng)建線程,不管用什么方法,最終都是靠線程來執(zhí)行的,而子線程的創(chuàng)建方式仍脫離不了最開始講的兩種基本方式,也就是實現(xiàn) Runnable 接口和繼承 Thread 類。

5:匿名內(nèi)部類、lambda表達式創(chuàng)建線程

    public static void innerClassThread(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("匿名內(nèi)部類創(chuàng)建線程");
            }
        }).start();
    }

    public static void lambdaThread(){
       new Thread(()->{
           System.out.println("lambda表達式創(chuàng)建線程");
       }).start();
    }

實際上,匿名內(nèi)部類或 lambda 表達式創(chuàng)建線程,它們僅僅是在語法層面上實現(xiàn)了線程,并不能把它歸結(jié)于實現(xiàn)多線程的方式,如匿名內(nèi)部類實現(xiàn)線程的代碼所示,它僅僅是用一個匿名內(nèi)部類把需要傳入的 Runnable 給實例出來。

二:為什么說本質(zhì)上只有一種實現(xiàn)線程的方式?

了解了上面的幾種創(chuàng)建線程的方式后,我們發(fā)現(xiàn)所有其他創(chuàng)建線程的方式都僅僅是在 new Thread() 外做了一層封裝而已;不同點僅僅在于實現(xiàn)線程運行內(nèi)容的不同。

  1. 實現(xiàn)線程執(zhí)行的內(nèi)容,通過實現(xiàn) Runnable 接口的方式

啟動線程需要調(diào)用 start() 方法,而 start() 方法最終還會調(diào)用 run() 方法,Thread中的run()方法源碼如下:

    /* What will be run. */
    private Runnable target;
    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }
  • target其實就是一個Runnable,實際線程執(zhí)行的內(nèi)容就是實現(xiàn)了Runnable的接口中的run方法。

  1. 實現(xiàn)線程執(zhí)行的內(nèi)容,繼承 Thread 類重寫 run() 方法的方式

  • 啟動線程需要調(diào)用 start() 方法,而 start() 方法最終還會調(diào)用 run() 方法,但是此時的run()方法,因為繼承的原因,此時已被子類重寫了,所以此時線程執(zhí)行的內(nèi)容是子類的run方法

運行內(nèi)容主要來自于兩個地方,要么來自于 target,要么來自于子類重寫的 run() 方法;因此可以這樣總結(jié):本質(zhì)上,實現(xiàn)線程只有一種方式new Thread(),而要想實現(xiàn)線程執(zhí)行的內(nèi)容,卻有兩種方式,要么通過實現(xiàn) Runnable 接口的方式,要么繼承 Thread 類重寫 run() 方法的方式,把我們想要執(zhí)行的代碼傳入,讓線程去執(zhí)行。

三:實現(xiàn) Runnable 接口究竟比繼承 Thread 類實現(xiàn)線程好在哪里?

  1. Runnable 里只有一個 run() 方法,它定義了需要執(zhí)行的內(nèi)容,在這種情況下,實現(xiàn)了 Runnable 與 Thread 類的解耦,Thread 類負責線程啟動和屬性設置等內(nèi)容,職責分明。

  2. java單繼承的原因,類一旦繼承了 Thread 類,那么它后續(xù)就沒有辦法再繼承其他的類,限制了代碼未來的可拓展性。

  3. 在某些情況下可以提高性能,如果使用繼承 Thread 類方式,每次執(zhí)行一次任務,都需要新建一個獨立的線程;使用實現(xiàn) Runnable 接口的方式,就可以把任務直接傳入線程池,使用一些固定的線程來完成任務,不需要每次新建銷毀線程,大大降低了性能開銷。

到此,關于“實現(xiàn)Java線程的方法有哪些”的學習就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關知識,請繼續(xù)關注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
分享標題:實現(xiàn)Java線程的方法有哪些
文章源于:http://weahome.cn/article/pchsge.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部