Java創建線程的兩種方式


方式

  • 繼承Thread類
  • 實現Runnable方法

實例

#繼承Thread類

public class ThreadTest2 extends Thread {
    private int threadCnt = 10;

    @Override
    public void run() {
        while (true) {
            if (threadCnt > 0) {
                System.out.println(Thread.currentThread().getName() + " 剩余個數 " + threadCnt);
                threadCnt--;
                try {
                    Thread.sleep(30);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                break;
            }
        }
    }

    public static void main(String[] args) {
        new ThreadTest2().start();
        new ThreadTest2().start();
    }
}

執行

Thread-1 剩余個數 10
Thread-0 剩余個數 10
Thread-0 剩余個數 9
Thread-1 剩余個數 9
Thread-0 剩余個數 8
Thread-1 剩余個數 8
Thread-0 剩余個數 7
Thread-1 剩余個數 7
Thread-1 剩余個數 6
Thread-0 剩余個數 6
Thread-1 剩余個數 5
Thread-0 剩余個數 5
Thread-1 剩余個數 4
Thread-0 剩余個數 4
Thread-1 剩余個數 3
Thread-0 剩余個數 3
Thread-0 剩余個數 2
Thread-1 剩余個數 2
Thread-0 剩余個數 1
Thread-1 剩余個數 1

 

#實現Runnable方法

public class RunnalbleTest2 implements Runnable {
    private int threadCnt = 10;

    @Override
    public void run() {
        while (true) {
            if (threadCnt > 0) {
                System.out.println(Thread.currentThread().getName() + " 剩余個數 " + threadCnt);
                threadCnt--;
                try {
                    Thread.sleep(30);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                break;
            }
        }
    }

    public static void main(String[] args) {
        RunnalbleTest2 runnalbleTest2 = new RunnalbleTest2();
        new Thread(runnalbleTest2).start();
        new Thread(runnalbleTest2).start();
        new Thread(runnalbleTest2).start();
        new Thread(runnalbleTest2).start();
    }
}

執行

Thread-0 剩余個數 10
Thread-1 剩余個數 10
Thread-2 剩余個數 8
Thread-3 剩余個數 7
Thread-1 剩余個數 6
Thread-3 剩余個數 5
Thread-2 剩余個數 6
Thread-0 剩余個數 6
Thread-1 剩余個數 2
Thread-0 剩余個數 2
Thread-2 剩余個數 2
Thread-3 剩余個數 2

可以看出該實例中雖然是2個線程,但操作的threadCnt卻是一個,實現了資源共享。

比較

實現接口的方式比繼承類的方式更靈活,也能減少程序之間的耦合度,面向接口編程也是設計模式6大原則的核心

start()方法和run()方法區別

涉及到線程的幾個狀態

新建狀態:使用 new 關鍵字和 Thread 類(或其子類)建立一個線程對象后,該線程對象就處於新建狀態。它保持這個狀態直到程序 start() 這個線程。

就緒狀態:當線程對象調用了start()方法之后,該線程就進入就緒狀態。就緒狀態的線程處於就緒隊列中,要等待JVM里線程調度器的調度。

運行狀態:如果就緒狀態的線程獲取到 CPU 資源,就可以執行 run(),此時線程便處於運行狀態。處於運行狀態的線程最為復雜,它可以變為阻塞狀態、就緒狀態和死亡狀態。

 

區別

只有調用了start()方法,才會表現出多線程的特性,不同線程的run()方法里面的代碼交替執行。如果只是調用run()方法,那么代碼還是同步執行的,必須等待一個線程的run()方法里面的代碼全部執行完畢之后,另外一個線程才可以執行其run()方法里面的代碼。測試如下

package com.jihite.helloworld.thread;

public class TestNoStart {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread() {
            @Override
            public void run() {
                pong(1);
                try {
                    Thread.sleep(7000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        Thread t2 = new Thread() {
            @Override
            public void run() {
                pong(2);
                try {
                    Thread.sleep(7000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        t1.start();
        t2.start();
//        t1.run();
//        t2.run();

        System.out.println("ping~~~~");
    }
    static void pong(int i) {
        System.out.println("pong~" + i);
    }
}

參考

Java 多線程編程

40個Java多線程問題總結

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM