国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Java實現線程的三種方式和區別

hyuan / 1142人閱讀

摘要:下面我們通過代碼來看一下實現和區別三種實現繼承,重寫方法實現接口,實現方法實現接口,實現方法,帶有返回值和異常如何使用第一種實現方式第二種實現方式第三種實現從代碼可以看出以上提到的區別,,。第二種方式并沒有體現共用同一個。

Java實現線程的三種方式和區別

Java實現線程的三種方式:

繼承Thread

實現Runnable接口

實現Callable接口

區別:

第一種方式繼承Thread就不能繼承其他類了,后面兩種可以;

使用后兩種方式可以多個線程共享一個target;

Callable比Runnable多一個返回值,并且call()方法可以拋出異常;

訪問線程名,第一種直接使用this.getName(),后兩種使用Thread.currentThread().getName()。

下面我們通過代碼來看一下實現和區別:

三種實現:

//1. 繼承Thread,重寫run()方法
class Thread1 extends Thread {
    
    private int n = 5;
    
    @Override
    public void run() {
        while(n > 0) {
            System.out.println("name:" + this.getName() + ", n:" + n);
            n--;
        }
    }
}
//2. 實現Runnable接口,實現run()方法
class Thread2 implements Runnable {
    
    private int n = 5; 
    
    @Override
    public void run() {
        while(n > 0) {
            System.out.println("name:" + Thread.currentThread().getName() + ", n:" + n);
            n--;
        }
    }
}
//3. 實現Callable接口,實現call()方法,帶有返回值和異常
class Thread3 implements Callable {
    
    private int n = 5;

    @Override
    public String call() throws Exception {
        while(n > 0) {
            System.out.println("name:" + Thread.currentThread().getName() + ", n:" + n);
            n--;
        }
        return String.valueOf(n);
    }
    
}

如何使用:

//第一種實現方式
Thread1 t11 = new Thread1();
Thread1 t12 = new Thread1();
Thread1 t13 = new Thread1();

t11.start();
t12.start();
t13.start();

//第二種實現方式
Thread2 t21 = new Thread2();
Thread2 t22 = new Thread2();
Thread2 t23 = new Thread2();

Thread t211 = new Thread(t21);
Thread t212 = new Thread(t22);
Thread t213 = new Thread(t23);

t211.start();
t212.start();
t213.start();

//第三種實現
Thread3 t31 = new Thread3();
Thread3 t32 = new Thread3();
Thread3 t33 = new Thread3();

FutureTask f1 = new FutureTask<>(t31);
FutureTask f2 = new FutureTask<>(t32);
FutureTask f3 = new FutureTask<>(t33);

Thread t311 = new Thread(f1);
Thread t312 = new Thread(f2);
Thread t313 = new Thread(f3);

t311.start();
t312.start();
t313.start();

從代碼可以看出以上提到的區別1,3,4。那么區別2共享一個target是什么意思呢?

首先我們看一下上述代碼的運行結果,

第一種:

name:Thread-1, n:5
name:Thread-1, n:4
name:Thread-1, n:3
name:Thread-1, n:2
name:Thread-1, n:1
name:Thread-2, n:5
name:Thread-2, n:4
name:Thread-2, n:3
name:Thread-2, n:2
name:Thread-2, n:1
name:Thread-0, n:5
name:Thread-0, n:4
name:Thread-0, n:3
name:Thread-0, n:2
name:Thread-0, n:1

第二種:

name:Thread-4, n:5
name:Thread-4, n:4
name:Thread-4, n:3
name:Thread-3, n:5
name:Thread-5, n:5
name:Thread-3, n:4
name:Thread-4, n:2
name:Thread-4, n:1
name:Thread-3, n:3
name:Thread-3, n:2
name:Thread-3, n:1
name:Thread-5, n:4
name:Thread-5, n:3
name:Thread-5, n:2
name:Thread-5, n:1

可以看到,這兩種方式的結果一樣,都是new了三個線程,每個線程內部循環5次。d第二種方式并沒有體現共用同一個target。如果我們將第二種創建線程的方式改為:

//第二種實現方式
Thread2 t21 = new Thread2();
Thread2 t22 = new Thread2();
Thread2 t23 = new Thread2();

Thread t211 = new Thread(t21);
Thread t212 = new Thread(t21);
Thread t213 = new Thread(t21);

t211.start();
t212.start();
t213.start();

看一下運行結果:

name:Thread-4, n:5
name:Thread-4, n:4
name:Thread-4, n:3
name:Thread-4, n:2
name:Thread-4, n:1
name:Thread-3, n:5
name:Thread-5, n:5

可以看到,雖然也啟動了3個線程,但是由于共享一個target,n的值改變了,其他兩個線程也會知道,所以因此一共循環了5次。但是這里明明是7次啊,這是由于多線程的同步問題,可以給run方法加上synchronized關鍵字解決:

@Override
public synchronized void run() {
  while(n > 0) {
    System.out.println("name:" + Thread.currentThread().getName() + ", n:" + n);
    n--;
  }
}

運行結果:

name:Thread-3, n:5
name:Thread-3, n:4
name:Thread-3, n:3
name:Thread-3, n:2
name:Thread-3, n:1

這里可能有點迷惑,只啟動了一個線程啊。其實另外兩個線程也啟動了,只是這個時候n=0無法進入循環。我們可以加一行打印:

@Override
public synchronized void run() {
  System.out.println("進入" + Thread.currentThread().getName() + "線程");
  while(n > 0) {
    System.out.println("name:" + Thread.currentThread().getName() + ", n:" + n);
    n--;
  }
}

可以看到運行結果:

進入Thread-3線程
name:Thread-3, n:5
name:Thread-3, n:4
name:Thread-3, n:3
name:Thread-3, n:2
name:Thread-3, n:1
進入Thread-5線程
進入Thread-4線程

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69056.html

相關文章

  • Hibernate最全面試題

    摘要:中怎樣實現類之間的關系如一對多多對多的關系中怎樣實現類之間的關系如一對多多對多的關系它們通過配置文件中的來實現類之間的關聯關系的。 Hibernate常見面試題 Hibernate工作原理及為什么要用? Hibernate工作原理及為什么要用? 讀取并解析配置文件 讀取并解析映射信息,創建SessionFactory 打開Sesssion 創建事務Transation 持久化操作 提...

    張利勇 評論0 收藏0
  • 史上最全阿里 Java 面試題總結

    摘要:以下為大家整理了阿里巴巴史上最全的面試題,涉及大量面試知識點和相關試題。的內存結構,和比例。多線程多線程的幾種實現方式,什么是線程安全。點擊這里有一套答案版的多線程試題。線上系統突然變得異常緩慢,你如何查找問題。 以下為大家整理了阿里巴巴史上最全的 Java 面試題,涉及大量 Java 面試知識點和相關試題。 JAVA基礎 JAVA中的幾種基本數據類型是什么,各自占用多少字節。 S...

    winterdawn 評論0 收藏0
  • Java程序員金三銀四精心挑選的300余道Java面試題與答案

    摘要:為程序員金三銀四精心挑選的余道面試題與答案,歡迎大家向我推薦你在面試過程中遇到的問題我會把大家推薦的問題添加到下面的常用面試題清單中供大家參考。 為Java程序員金三銀四精心挑選的300余道Java面試題與答案,歡迎大家向我推薦你在面試過程中遇到的問題,我會把大家推薦的問題添加到下面的常用面試題清單中供大家參考。 前兩天寫的以下博客,大家比較認可,熱度不錯,希望可以幫到準備或者正在參加...

    tomorrowwu 評論0 收藏0
  • #yyds干貨盤點#Apache三種模式

    1.Apache prefork模型:apache的默認的模型預派 生模式,有 一個主控制進程,然后 生成多個 子進程,使 用select模型,最 大并發1024,每個 子進程有 一個獨 立的線程響應 用戶請求,相對 比較占 用內存,但是 比較穩定,可以設置最 大和最 小進程數,是最古 老 的 一種模式,也是最穩定的模式,適 用于訪問量 不 是很 大的場景。優點:穩定缺點: 大量 用戶訪問慢,占...

    loonggg 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<