溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java線程創建方式有哪些

發布時間:2021-09-14 11:26:15 來源:億速云 閱讀:128 作者:柒染 欄目:開發技術

這篇文章給大家介紹Java線程創建方式有哪些,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

多線程的創建,方式一:繼承于Thread類

1.創建一個繼承于Thread類的子類

2.重寫Thread類的run()--->將此線程執行的操作聲明在run()中

3.創建Thread類的子類的對象

4.通過此對象調用start():

start()方法的兩個作用:

A.啟動當前線程

B.調用當前線程的run()

創建過程中的兩個問題:

問題一:我們不能通過直接調用run()的方式啟動線程

問題二:在啟動一個線程,遍歷偶數,不可以讓已經start()的線程去執行,會報異常;正確的方式是重新創建一個線程的對象。

//1.創建一個繼承于Thread類的子類
class MyThread extends Thread{
    //2.重寫Thread類的run()
    @Override
    public void run() {//第二個線程
       for(int i = 0;i < 10;i++){
           if(i % 2 == 0){
               System.out.println(i);
           }
       }
    }
}
public class ThreadTest {
    public static void main(String[] args) {//主線程
        //3.創建Thread類的子類的對象
        MyThread t1 = new MyThread();
        //4.通過此對象調用start()
        t1.start();
        //問題一:不能通過直接調用run()的方式啟動線程
//        t1.run();//錯誤的
        //問題二:再啟動一個線程:我們需要再創建 一個對象
        //t1.start();//錯誤的
        MyThread t2 = new MyThread();
        t2.start();
 
        for(int i = 0;i < 10;i++){
            if(i % 2 != 0){
                System.out.println(i + "****main()******");
            }
        }
    }
}

此代碼在主線程內輸出奇數,在另一個線程里輸出偶數,則輸出結果應該是兩個輸出結果是交互的。

1****main()******
3****main()******
5****main()******
7****main()******
0
2
4
6
8
9****main()******

class Window extends Thread{//創建三個窗口賣票, 總票數為100張,使用繼承于Thread類的方式
    private static int ticket = 100;//三個窗口共享:聲明為static
    @Override
    public void run() {
        while(true){
            if(ticket > 0){
                System.out.println(getName() + ":賣票,票號為:" + ticket);
                ticket--;
            }else{
                break;
            }
        }
    }
}
public class WindowTest2 {
    public static void main(String[] args) {
        Window t1 = new Window();
        Window t2 = new Window();
        Window t3 = new Window();
        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");
        t1.start();
        t2.start();
        t3.start();
    }
}
public class ThreadDemo {
    public static void main(String[] args) {
//        MyThread1 m1 = new MyThread1();
//        MyThread2 m2 = new MyThread2();
//        m1.start();
//        m2.start();
        //由于造的類只創建過一次對象,后面就不用了,可以考慮使用匿名類的方式
        //創建Thread類的匿名子類的方式
        new Thread(){
            @Override
            public void run() {
                for(int i = 0;i < 100;i++){
                    if(i % 2 == 0){
                        System.out.println(i);
                    }
                }
            }
        }.start();
        new Thread(){
            @Override
            public void run() {
                for(int i = 0;i < 100;i++){
                    if(i % 2 != 0){
                        System.out.println(i);
                    }
                }
            }
        }.start();
    }
}
class MyThread1 extends Thread{
    @Override
    public void run() {
        for(int i = 0;i < 100;i++){
            if(i % 2 == 0){
                System.out.println(i);
            }
        }
    }
}
class MyThread2 extends Thread{
    @Override
    public void run() {
        for(int i = 0;i < 100;i++){
            if(i % 2 != 0){
                System.out.println(i);
            }
        }
    }
}

創建多線程的方式二:實現Runnable接口

  • 創建一個實現了Runnable接口的類

  • 實現類去實現Runnable中的抽象方法:run()

  • 創建實現類的對象

  • 將此對象作為參數傳遞到Thread類的構造器中,創建Thread類的對象

  • 通過Thread類的對象調用start()

class MThread implements Runnable{
    //2.實現類去實現Runnable中的抽象方法:run()
    @Override
    public void run() {
        for(int i = 0;i < 100;i++){
            if (i % 2 == 0) {
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
        }
    }
}
public class ThreadTest1 {
    public static void main(String[] args) {
        //3.創建實現類的對象
        MThread mThread = new MThread();
        //4.將此對象作為參數傳遞到Thread類的構造器中,創建Thread類的對象
        Thread t1 = new Thread(mThread);
        t1.setName("線程1");
        //5.通過Thread類的對象調用start():A.啟動線程B.調用當前線程的run()-->調用了Runnable類型的target
        t1.start();
        //再啟動一個線程,遍歷100以內的偶數//只需重新實現步驟4,5即可
        Thread t2 = new Thread(mThread);
        t2.setName("線程2");
        t2.start();
    }
}
class window1 implements Runnable{//創建三個窗口賣票, 總票數為100張,使用實現Runnable接口的方式
    private int ticket = 100;
    Object obj = new Object();
    @Override
    public void run() {
        while (true){
            if (ticket > 0) {
                System.out.println(Thread.currentThread().getName() + "賣票,票號為:" + ticket);
                ticket--;
            } else {
                break;
            }
        }
    }
}
public class WindowTest {
    public static void main(String[] args) {
        window1 w = new window1();//只造了一個對象,所以100張票共享
        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);
        t1.setName("線程1");
        t2.setName("線程2");
        t3.setName("線程3");
        t1.start();
        t2.start();
        t3.start();
    }
}

創建線程的方式三:實現Callable接口---JDK5.0新增

與使用Runnable相比,Callable功能更強大些

>相比run()方法,可以有返回值

>方法可以拋出異常

>支持泛型的返回值

>需要借助FutureTask類,比如獲取返回結果

Future接口

>可以對具體Runnable、Callable任務的執行結果進行取消、查詢是否完成、獲取結果等。

>FutureTask是Futrue接口的唯一的實現類

>FutureTaskb同時實現了Runnable,Future接口。它既可以作為Runnable被線程執行,又可以作為Future得到Callable的返回值

//1.創建一個實現Callable的實現類
class NumThread implements Callable{
    //2.實現call方法,將此線程需要執行的操作聲明在call()中
    @Override
    public Object call() throws Exception {
        int sum = 0;
        for(int i = 1;i <= 100;i++){
            if(i % 2 == 0){
                System.out.println(i);
                sum += i;
            }
        }
        return sum;//sum是int,自動裝箱為Integer(Object的子類)
    }
}
public class ThreadNew {
    public static void main(String[] args) {
        //3.創建Callable接口實現類的對象
        NumThread numThread = new NumThread();
        //4.將此Callable接口實現類的對象作為參數傳遞到 FutureTask的構造器中,創建FutureTask的對象
        FutureTask futureTask = new FutureTask(numThread);
        //5.將 FutureTask的對象作為參數傳遞到Thread類的構造器中,創建Thread對象,并調用start()
        new Thread(futureTask).start();
        try {
            //獲取Callable中call()的返回值(不是必須的步驟)
            //get()返回值即為FutureTask構造器參數Callable實現類重寫的call()的返回值。
            Object sum = futureTask.get();
            System.out.println("總和為:" + sum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

創建線程的方式四:使用線程池--->JDK5.0新增

背景:經常創建和銷毀、使用量特別大的資源,比如并發情況下的線程,對性能影響很大。

思路:提前創建好多個線程,放入線程池中,使用時直接獲取,使用完放回池中??梢员苊忸l繁創建銷毀、實現重復利用。類似生活中的公共交通工具。

好處:>提高響應速度(減少了創建新線程的時間)

>降低資源消耗(重復利用線程池中線程,不需要每次都創建)

>便于線程管理:A.corePoolSize:核心池的大小 B.maximumPoolSize:最大線程數 C.keepAliveTime:線程沒有任務時最多保持多長時間后會終止

Java線程創建方式有哪些

class NumberThread implements Runnable{
 
    @Override
    public void run() {
        for(int i = 0;i <= 100;i++){
            if(i % 2 == 0){
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
        }
    }
}
class NumberThread1 implements Runnable{
    @Override
    public void run() {
        for(int i = 0;i <= 100;i++){
            if(i % 2 != 0){
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
        }
    }
}
public class ThreadPool {
    public static void main(String[] args) {
        //1.提供指定線程數量的線程池
        ExecutorService service = Executors.newFixedThreadPool(10);
        ThreadPoolExecutor service1 = (ThreadPoolExecutor) service;
        //設置線程池的屬性
//        System.out.println(service.getClass());
//        service1.setCorePoolSize(15);
//        service1.setKeepAliveTime();
        //2.執行指定的線程操作。需要提供實現Runnable 接口或Callable接口實現類的對象
        service.execute(new NumberThread());//適用于Runnable
        service.execute(new NumberThread1());//適用于Runnable
//        service.submit(Callable callable);//適用于Callable
        //3.關閉連接池
        service.shutdown();
    }
}

比較創建線程的兩種方式:

開發中:優先選擇:實現Runnable接口的方式
原因:1.實現的方式沒有類的單繼承性的局限性
2.實現的方式更適合來處理多個線程有共享數據的情況。
系:public class Thread implements Runnable
相同點:兩種方式都需要重寫run(),將線程要執行的邏輯聲明在run()中

Java線程創建方式有哪些

程序(program)是為完成特定任務、用某種語言編寫的一組指令的集合。即指一段靜態的代碼,靜態對象。

進程(process)是程序的一次執行過程,或是正在運行的一個程序。是一個動態的過程:有它自身的產生、存在和消亡的過程。---生命周期

線程(thread),進程可進一步細化為線程,是一個程序內部的一條執行路徑。

Java線程創建方式有哪些

線程作為調度和執行的單位,每個線程擁有獨立的運行棧和計數器,每個進程擁有獨立的方法區和堆;意味著,多個線程共享一個方法區和堆。而共享的就可以優化,同時,共享的也會帶來安全隱患,這就需要我們解決線程安全問題

背景:以單核CPU為例,只使用單個線程先后完成多個任務(調用多個方法),肯定比用多個線程來完成用的時間更短,為何仍需使用多線程呢?

使用多線程的優點:

1.提高應用程序的響應。對圖形化界面更有意義,可增強用戶體驗。

2.提高計算機系統CPU的利用率

3.改善程序結構。將即長又復雜的線程分為多個線程,獨立運行,利于理解和修改

何時需要多線程

1.程序需要同時執行兩個或多個任務。

2.程序需要實現一些需要等待的任務時,如用戶輸入、文件讀寫操作、網絡操作、搜索等。

3.需要一些后臺運行的程序時。

public class Sample{
    public void method1(String str){
        System.out.println(str);
    }
    public void method2(String str){
        method1(str);
    }
    public static void main(String[] args){
        Sample s = new Sample();
        s.method2("hello!");
    }
}

注意:此程序不是多線程!main方法中調用了method1,method1中又調用了method2;是一條執行路徑,所以是單線程

測試Thread類的常用方法:

1.start():啟動當前線程:調用當前線程的run()
2.run():通常需要重寫Thread類中的此方法,將創建的線程要執行的操作聲明在此方法中
3.currentThread():靜態方法,返回執行當前代碼的線程
4.getName():獲取當前線程的名字
5.setName():設置當前線程的名字
6.yield():釋放當前CPU的執行權(下一刻CPU執行的線程仍是隨機的)
>暫停當前正在執行的線程,把執行機會讓給優先級相同或更高的線程
>若隊列中沒有同優先級的線程,忽略此方法
7.join():在線程a中調用線程b的join(),此時,線程a就進入阻塞狀態(停止執行),直到線程b完全執行完以后,線程b才結束阻塞狀態(開始執行)。
8.sleep(long millitime):讓當前線程"睡眠"指定的millitime毫秒。在指定的millitime毫秒時間內,當前線程是阻塞狀態。會拋出InterruptedException異常
* 9.isAlive():判斷當前線程是否存活

class HelloThread extends Thread{
    @Override
    public void run() {
        for(int i = 0;i < 100;i++){
            if(i % 2 != 0){
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ":" +Thread.currentThread().getPriority() + ":" + i);
            }
        }
    }
    public HelloThread(String name){
        super(name);
    }
}
public class ThreadMethodTest {
    public static void main(String[] args) {
        HelloThread h2 = new HelloThread("Thread:1");//通過構造器給線程命名,但前期是得在子類中提供一個構造器
//        h2.setName("線程一");
        //設置分線程的優先級
        h2.setPriority(Thread.MAX_PRIORITY);
        h2.start();
        //給主線程命名
        Thread.currentThread().setName("主線程");
        Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
        for(int i = 0;i < 100;i++){
            if(i % 2 == 0) {
                System.out.println(Thread.currentThread().getName() + ":" + Thread.currentThread().getPriority() + ":" + i);
            }
//            if(i == 20){
//                try {
//                    h2.join();//join()的測試
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }
        }
    }
}

線程的優先級:

1.MAX_PRIORITY:10
MIN_PRIORITY:1
NORM_PRIORITY:5--->默認優先級
2.如何獲取和設置當前線程的優先級:
getPriority():獲取線程的優先級
setPriority(int p):設置線程的優先級
說明:高優先級的線程要搶占低優先級線程CPU的執行權,但是只是從概率上講,高優先級的線程高概率的情況下,不一定被執行,并不意味著只有當高優先級的線程執行完畢后,低優先級的線程才執行。

Java線程創建方式有哪些

Java線程創建方式有哪些

關于Java線程創建方式有哪些就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女