成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

深入淺出、玩轉(zhuǎn)Java多線程

開(kāi)發(fā) 前端
Java多線程是提高程序并發(fā)性和響應(yīng)能力的重要手段,需要掌握多線程的實(shí)現(xiàn)方式、同步機(jī)制、線程之間的通信機(jī)制等,以確保多線程程序的正確性和穩(wěn)定性。

哈嘍,大家好,我是了不起。

Java多線程是Java編程語(yǔ)言的一個(gè)特性,它允許程序在同一時(shí)間執(zhí)行多個(gè)任務(wù)。使用多線程可以充分利用計(jì)算機(jī)的多核處理器,提高程序的性能和響應(yīng)速度。

本文將介紹一下Java多線程的用法。

基礎(chǔ)介紹

什么是多線程

指的是在一個(gè)進(jìn)程中同時(shí)運(yùn)行多個(gè)線程,每個(gè)線程都可以獨(dú)立執(zhí)行不同的任務(wù)或操作。 與單線程相比,多線程可以提高程序的并發(fā)性和響應(yīng)能力。

什么是進(jìn)程

是指正在運(yùn)行的程序的實(shí)例。

每個(gè)進(jìn)程都擁有自己的內(nèi)存空間、代碼、數(shù)據(jù)和文件等資源,可以獨(dú)立運(yùn)行、調(diào)度和管理。在操作系統(tǒng)中,進(jìn)程是系統(tǒng)資源分配的最小單位,是實(shí)現(xiàn)多任務(wù)的基礎(chǔ)。

Java多線程

Java多線程是指在一個(gè)Java程序中同時(shí)執(zhí)行多個(gè)線程,它可以提高程序的并發(fā)性和響應(yīng)能力。Java中實(shí)現(xiàn)多線程的方式:

  • 繼承Thread類
  • 實(shí)現(xiàn)Runnable接口
  • Executor框架
  • Callable
  • Future
  • 線程池

繼承Thread類

繼承Thread類是實(shí)現(xiàn)多線程的一種方式,只需要繼承Thread類并重寫run()方法即可。

public class ThreadDemo {
    public static void main(String[] args) {
        // 創(chuàng)建10個(gè)線程并啟動(dòng)
        for (int i = 0; i < 10; i++) {
            MyThread thread = new MyThread(i);
            thread.start();
        }
    }
}
 
class MyThread extends Thread {
    private int id;
 
    public MyThread(int id) {
        this.id = id;
    }
 
    public void run() {
        System.out.println("Thread " + id + " is running");
        try {
            Thread.sleep(1000);  // 模擬任務(wù)執(zhí)行時(shí)間
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

以上代碼中,首先創(chuàng)建了一個(gè)ThreadDemo類,在main函數(shù)中創(chuàng)建了10個(gè)線程,并啟動(dòng)這些線程。

每個(gè)線程都是MyThread類的實(shí)例,MyThread類繼承了Thread類,并重寫了run()方法,在方法中模擬了一個(gè)需要執(zhí)行1秒鐘的任務(wù)。

在main函數(shù)中,通過(guò)創(chuàng)建MyThread類的實(shí)例,并調(diào)用start()方法啟動(dòng)線程。start()方法會(huì)調(diào)用線程的run()方法,在run()方法中執(zhí)行線程的任務(wù)。

實(shí)現(xiàn)Runnable接口

另一種實(shí)現(xiàn)多線程的方式是實(shí)現(xiàn)Runnable接口,需要實(shí)現(xiàn)run()方法,并將實(shí)現(xiàn)了Runnable接口的對(duì)象傳遞給Thread類的構(gòu)造函數(shù)。

public class RunnableDemo {
    public static void main(String[] args) {
        // 創(chuàng)建10個(gè)線程并啟動(dòng)
        for (int i = 0; i < 10; i++) {
            Runnable task = new MyTask(i);
            Thread thread = new Thread(task);
            thread.start();
        }
    }
}
 
class MyTask implements Runnable {
    private int id;
 
    public MyTask(int id) {
        this.id = id;
    }
 
    public void run() {
        System.out.println("Thread " + id + " is running");
        try {
            Thread.sleep(1000);  // 模擬任務(wù)執(zhí)行時(shí)間
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

以上代碼中,創(chuàng)建了一個(gè)RunnableDemo類,在main函數(shù)中創(chuàng)建了10個(gè)線程,并啟動(dòng)這些線程。

每個(gè)線程都是MyTask類的實(shí)例,MyTask類實(shí)現(xiàn)了Runnable接口,并重寫了run()方法,在方法中模擬了一個(gè)需要執(zhí)行1秒鐘的任務(wù)。

在main函數(shù)中,通過(guò)創(chuàng)建MyTask類的實(shí)例,并創(chuàng)建一個(gè)Thread對(duì)象,將Runnable對(duì)象作為參數(shù)傳遞給Thread構(gòu)造方法,最后調(diào)用start()方法啟動(dòng)線程。start()方法會(huì)調(diào)用線程的run()方法,在run()方法中執(zhí)行線程的任務(wù)。

在使用實(shí)現(xiàn)Runnable接口實(shí)現(xiàn)多線程時(shí),可以更好地分離任務(wù)和線程,并提高代碼的可擴(kuò)展性和可維護(hù)性。

如果需要添加更多的線程或任務(wù),只需要?jiǎng)?chuàng)建更多的Runnable實(shí)例,并創(chuàng)建對(duì)應(yīng)的Thread對(duì)象即可,不需要?jiǎng)?chuàng)建更多的線程類,并且可以更好地重用代碼。

Executor框架

Executor框架是Java提供的一個(gè)線程池框架,用于管理和調(diào)度多個(gè)線程。通過(guò)Executor框架,可以更方便地實(shí)現(xiàn)多線程,避免手動(dòng)管理線程帶來(lái)的復(fù)雜性和風(fēng)險(xiǎn)。

Executor框架的核心接口是Executor和ExecutorService,

  1. Executor是一個(gè)簡(jiǎn)單的線程池接口,只有一個(gè)execute()方法,用于提交一個(gè)Runnable任務(wù)給線程池執(zhí)行。
  2. ExecutorService是Executor的擴(kuò)展接口,提供了更多的管理和調(diào)度線程的方法,如submit()、shutdown()、awaitTermination()等。

使用Executor框架實(shí)現(xiàn)多線程,通常需要以下步驟:

  1. 創(chuàng)建一個(gè)ExecutorService對(duì)象,可以使用Executors類提供的靜態(tài)方法創(chuàng)建線程池,如newFixedThreadPool()、newCachedThreadPool()、newSingleThreadExecutor()等。
  2. 將需要執(zhí)行的任務(wù)封裝成一個(gè)Runnable或Callable對(duì)象,可以使用Java中的匿名內(nèi)部類或Lambda表達(dá)式來(lái)創(chuàng)建。
  3. 將任務(wù)提交給ExecutorService對(duì)象執(zhí)行,可以使用submit()方法提交Callable對(duì)象,或使用execute()方法提交Runnable對(duì)象。
  4. 在程序完成時(shí),調(diào)用shutdown()方法關(guān)閉線程池,或使用awaitTermination()方法等待所有線程執(zhí)行完畢。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
public class ExecutorDemo {
    public static void main(String[] args) {
        // 創(chuàng)建一個(gè)包含10個(gè)線程的線程池
        ExecutorService executor = Executors.newFixedThreadPool(10);
 
        // 提交10個(gè)任務(wù)給線程池執(zhí)行
        for (int i = 0; i < 10; i++) {
            executor.execute(new MyTask(i));
        }
 
        // 關(guān)閉線程池
        executor.shutdown();
    }
}
 
class MyTask implements Runnable {
    private int id;
 
    public MyTask(int id) {
        this.id = id;
    }
 
    public void run() {
        System.out.println("Thread " + id + " is running");
        try {
            Thread.sleep(1000);  // 模擬任務(wù)執(zhí)行時(shí)間
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在上面的例子中,先創(chuàng)建了一個(gè)ExecutorDemo類,在main函數(shù)中創(chuàng)建了一個(gè)包含10個(gè)線程的線程池。

每個(gè)線程池中的線程都可以執(zhí)行MyTask類的實(shí)例,MyTask類實(shí)現(xiàn)了Runnable接口,并重寫了run()方法,在方法中模擬了一個(gè)需要執(zhí)行1秒鐘的任務(wù)。

在main函數(shù)中,創(chuàng)建MyTask類的實(shí)例,并調(diào)用ExecutorService的execute()方法提交給線程池執(zhí)行。

execute()方法會(huì)將任務(wù)提交給線程池中的一個(gè)空閑線程執(zhí)行。

最后調(diào)用ExecutorService的shutdown()方法關(guān)閉線程池。

需要注意的是,shutdown()方法會(huì)等待所有線程執(zhí)行完畢后才會(huì)關(guān)閉線程池,如果需要立即關(guān)閉線程池,可以使用shutdownNow()方法。

Callable實(shí)現(xiàn)多線程

Callable是Java中的一個(gè)接口,與Runnable接口類似,都用于封裝一個(gè)線程執(zhí)行的任務(wù)。

不同的是,Callable接口的call()方法可以返回一個(gè)結(jié)果,而Runnable接口的run()方法沒(méi)有返回值。

使用Callable實(shí)現(xiàn)多線程,通常需要以下步驟:

  1. 創(chuàng)建一個(gè)實(shí)現(xiàn)了Callable接口的類,實(shí)現(xiàn)call()方法,并在方法中編寫線程執(zhí)行的代碼。
  2. 創(chuàng)建一個(gè)ExecutorService對(duì)象,可以使用Executors類提供的靜態(tài)方法創(chuàng)建線程池,如newFixedThreadPool()、newCachedThreadPool()、newSingleThreadExecutor()等。
  3. 將Callable對(duì)象提交給ExecutorService對(duì)象執(zhí)行,可以使用submit()方法提交。
  4. 調(diào)用Future對(duì)象的get()方法獲取Callable線程執(zhí)行的結(jié)果。
  5. 在程序完成時(shí),調(diào)用shutdown()方法關(guān)閉線程池,或使用awaitTermination()方法等待所有線程執(zhí)行完畢。
import java.util.concurrent.*;
 
public class CallableDemo {
    public static void main(String[] args) throws Exception {
        // 創(chuàng)建一個(gè)線程池
        ExecutorService executor = Executors.newFixedThreadPool(10);
 
        // 提交10個(gè)Callable任務(wù)給線程池執(zhí)行
        Future<Integer>[] results = new Future[10];
        for (int i = 0; i < 10; i++) {
            Callable<Integer> task = new MyTask(i);
            results[i] = executor.submit(task);
        }
 
        // 輸出Callable任務(wù)的執(zhí)行結(jié)果
        for (int i = 0; i < 10; i++) {
            Integer result = results[i].get();
            System.out.println("Task " + i + " result is " + result);
        }
 
        // 關(guān)閉線程池
        executor.shutdown();
    }
}
 
class MyTask implements Callable<Integer> {
    private int id;
 
    public MyTask(int id) {
        this.id = id;
    }
 
    public Integer call() throws Exception {
        System.out.println("Task " + id + " is running");
        Thread.sleep(1000);  // 模擬任務(wù)執(zhí)行時(shí)間
        return id * 10;
    }
}

首先創(chuàng)建一個(gè)線程池,然后提交10個(gè)Callable任務(wù)給線程池執(zhí)行。每個(gè)Callable任務(wù)都是MyTask類的實(shí)例,MyTask類實(shí)現(xiàn)了Callable接口,并重寫了call()方法,在方法中模擬了一個(gè)需要執(zhí)行1秒鐘的任務(wù),并返回一個(gè)結(jié)果。

詳細(xì)解釋如下:

  1. 創(chuàng)建一個(gè)線程池,通過(guò)調(diào)用Executors的靜態(tài)方法newFixedThreadPool(10),創(chuàng)建了一個(gè)固定大小為10的線程池。
  2. 在for循環(huán)中,通過(guò)創(chuàng)建MyTask類的實(shí)例,將其封裝為Callable對(duì)象,并通過(guò)ExecutorService的submit()方法提交給線程池執(zhí)行。submit()方法會(huì)返回一個(gè)Future對(duì)象,代表了Callable任務(wù)的執(zhí)行結(jié)果。
  3. 在for循環(huán)中,通過(guò)Future數(shù)組記錄每個(gè)Callable任務(wù)的執(zhí)行結(jié)果,可以通過(guò)調(diào)用get()方法獲取Callable任務(wù)的執(zhí)行結(jié)果。如果Callable任務(wù)還沒(méi)有執(zhí)行完成,get()方法會(huì)阻塞當(dāng)前線程,直到任務(wù)執(zhí)行完成并返回結(jié)果。如果任務(wù)執(zhí)行過(guò)程中發(fā)生異常,get()方法會(huì)拋出ExecutionException異常。
  4. 在任務(wù)完成后,可以通過(guò)調(diào)用Future對(duì)象的get()方法獲取任務(wù)的執(zhí)行結(jié)果,并打印輸出。
  5. 最后調(diào)用ExecutorService的shutdown()方法關(guān)閉線程池,應(yīng)該在所有任務(wù)執(zhí)行完成后才能關(guān)閉線程池。

注意,在使用Callable實(shí)現(xiàn)多線程時(shí),要考慮線程安全、同步機(jī)制、任務(wù)調(diào)度和管理等問(wèn)題,以確保程序的正確性和穩(wěn)定性。

同時(shí),由于Callable任務(wù)的執(zhí)行時(shí)間可能會(huì)比較長(zhǎng),可以設(shè)置超時(shí)時(shí)間來(lái)避免任務(wù)執(zhí)行時(shí)間過(guò)長(zhǎng)導(dǎo)致的程序阻塞。

Future實(shí)現(xiàn)多線程

Future是Java中的一個(gè)接口,用于異步獲取任務(wù)執(zhí)行結(jié)果。

在多線程編程中,可以使用Future來(lái)獲取異步任務(wù)的執(zhí)行結(jié)果,以便在任務(wù)完成后進(jìn)行處理或展示。

使用Future實(shí)現(xiàn)多線程,需要以下步驟:

  1. 創(chuàng)建一個(gè)實(shí)現(xiàn)了Callable接口的類,實(shí)現(xiàn)call()方法,并在方法中編寫線程執(zhí)行的代碼。
  2. 創(chuàng)建一個(gè)ExecutorService對(duì)象,可以使用Executors類提供的靜態(tài)方法創(chuàng)建線程池,如newFixedThreadPool()、newCachedThreadPool()、newSingleThreadExecutor()等。
  3. 將Callable對(duì)象提交給ExecutorService對(duì)象執(zhí)行,可以使用submit()方法提交,submit()方法會(huì)返回一個(gè)Future對(duì)象。
  4. 調(diào)用Future對(duì)象的get()方法獲取Callable線程執(zhí)行的結(jié)果。如果任務(wù)還沒(méi)有執(zhí)行完成,get()方法會(huì)阻塞當(dāng)前線程直到任務(wù)執(zhí)行完成并返回結(jié)果。
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
 
public class FutureDemo {
    public static void main(String[] args) throws Exception {
        // 創(chuàng)建一個(gè)線程池
        ExecutorService executor = Executors.newFixedThreadPool(10);
 
        // 提交10個(gè)Callable任務(wù)給線程池執(zhí)行
        List<Future<Integer>> results = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Callable<Integer> task = new MyTask(i);
            Future<Integer> result = executor.submit(task);
            results.add(result);
        }
 
        // 輸出Callable任務(wù)的執(zhí)行結(jié)果
        for (int i = 0; i < 10; i++) {
            Integer result = results.get(i).get();
            System.out.println("Task " + i + " result is " + result);
        }
 
        // 關(guān)閉線程池
        executor.shutdown();
    }
}
 
class MyTask implements Callable<Integer> {
    private int id;
 
    public MyTask(int id) {
        this.id = id;
    }
 
    public Integer call() throws Exception {
        System.out.println("Task " + id + " is running");
        Thread.sleep(1000);  // 模擬任務(wù)執(zhí)行時(shí)間
        return id * 10;
    }
}

在以上示例中:

  1. 首先創(chuàng)建了一個(gè)線程池,然后提交10個(gè)Callable任務(wù)給線程池執(zhí)行。每個(gè)Callable任務(wù)都是MyTask類的實(shí)例,MyTask類實(shí)現(xiàn)了Callable接口,并重寫了call()方法,在方法中模擬了一個(gè)需要執(zhí)行1秒鐘的任務(wù),并返回一個(gè)結(jié)果。
  2. 在main函數(shù)中,使用List記錄每個(gè)Callable任務(wù)的執(zhí)行結(jié)果的Future對(duì)象,并在任務(wù)完成后通過(guò)調(diào)用get()方法獲取Callable任務(wù)的執(zhí)行結(jié)果。如果任務(wù)還沒(méi)有執(zhí)行完成,get()方法會(huì)阻塞當(dāng)前線程直到任務(wù)執(zhí)行完成并返回結(jié)果。
  3. 最后關(guān)閉線程池。

線程池實(shí)現(xiàn)多線程

線程池是Java中提供的一個(gè)用于管理和復(fù)用多個(gè)線程的框架,可以有效地提高多線程應(yīng)用程序的性能和可靠性。

使用線程池實(shí)現(xiàn)多線程,通常需要以下步驟:

  1. 創(chuàng)建一個(gè)線程池,可以使用Executors類提供的靜態(tài)方法創(chuàng)建線程池,如newFixedThreadPool()、newCachedThreadPool()、newSingleThreadExecutor()等。
  2. 創(chuàng)建一個(gè)實(shí)現(xiàn)了Runnable接口或Callable接口的類,實(shí)現(xiàn)run()方法或call()方法,并在方法中編寫線程執(zhí)行的代碼。
  3. 將Runnable對(duì)象或Callable對(duì)象提交給線程池執(zhí)行,可以使用submit()方法提交,submit()方法會(huì)返回一個(gè)Future對(duì)象。
  4. 關(guān)閉線程池,可以調(diào)用shutdown()方法或shutdownNow()方法。
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
 
public class ThreadPoolDemo {
    public static void main(String[] args) throws Exception {
        // 創(chuàng)建一個(gè)包含10個(gè)線程的線程池
        ExecutorService executor = Executors.newFixedThreadPool(10);
 
        // 提交10個(gè)任務(wù)給線程池執(zhí)行,并記錄每個(gè)任務(wù)的執(zhí)行結(jié)果
        List<Future<Integer>> results = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Callable<Integer> task = new MyTask(i);
            Future<Integer> result = executor.submit(task);
            results.add(result);
        }
 
        // 等待所有任務(wù)執(zhí)行完成
        executor.shutdown();
        executor.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
 
        // 輸出所有任務(wù)的執(zhí)行結(jié)果
        int total = 0;
        for (int i = 0; i < 10; i++) {
            try {
                Integer result = results.get(i).get();
                System.out.println("Task " + i + " result is " + result);
                total += result;
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                System.out.println("Task " + i + " execution error: " + e.getCause().getMessage());
            }
        }
        System.out.println("Total result is " + total);
    }
}
 
class MyTask implements Callable<Integer> {
    private int id;
 
    public MyTask(int id) {
        this.id = id;
    }
 
    public Integer call() throws Exception {
        System.out.println("Task " + id + " is running");
        Thread.sleep(2000);  // 模擬任務(wù)執(zhí)行時(shí)間
        if (id % 2 == 0) {
            throw new RuntimeException("Task " + id + " execution error");
        }
        return id * 10;
    }
}

在以上示例中,首先創(chuàng)建了一個(gè)包含10個(gè)線程的線程池,然后提交10個(gè)任務(wù)給線程池執(zhí)行。每個(gè)任務(wù)都是MyTask類的實(shí)例,MyTask類實(shí)現(xiàn)了Callable接口,并重寫了call()方法,在方法中模擬了一個(gè)需要執(zhí)行2秒鐘的任務(wù),并返回一個(gè)結(jié)果。

其中,如果任務(wù)的id是偶數(shù),會(huì)拋出一個(gè)運(yùn)行時(shí)異常。

在main函數(shù)中,使用List記錄每個(gè)任務(wù)的執(zhí)行結(jié)果的Future對(duì)象,并在任務(wù)完成后通過(guò)調(diào)用get()方法獲取任務(wù)的執(zhí)行結(jié)果。

如果任務(wù)還沒(méi)有執(zhí)行完成,get()方法會(huì)阻塞當(dāng)前線程直到任務(wù)執(zhí)行完成并返回結(jié)果。

在所有任務(wù)提交給線程池后,調(diào)用ExecutorService的shutdown()方法關(guān)閉線程池,并調(diào)用awaitTermination()方法等待所有任務(wù)執(zhí)行完成。

最后輸出所有任務(wù)的執(zhí)行結(jié)果,并計(jì)算所有任務(wù)的執(zhí)行結(jié)果的總和。

總結(jié)

總之,Java多線程是提高程序并發(fā)性和響應(yīng)能力的重要手段,需要掌握多線程的實(shí)現(xiàn)方式、同步機(jī)制、線程之間的通信機(jī)制等,以確保多線程程序的正確性和穩(wěn)定性。

責(zé)任編輯:武曉燕 來(lái)源: Java技術(shù)指北
相關(guān)推薦

2009-06-29 15:25:00

Java多線程

2022-09-29 09:19:04

線程池并發(fā)線程

2021-03-16 08:54:35

AQSAbstractQueJava

2011-07-04 10:39:57

Web

2019-01-07 15:29:07

HadoopYarn架構(gòu)調(diào)度器

2021-07-20 15:20:02

FlatBuffers阿里云Java

2012-05-21 10:06:26

FrameworkCocoa

2017-07-02 18:04:53

塊加密算法AES算法

2022-09-26 09:01:15

語(yǔ)言數(shù)據(jù)JavaScript

2022-01-11 07:52:22

CSS 技巧代碼重構(gòu)

2025-03-27 09:38:35

2021-04-27 08:54:43

ConcurrentH數(shù)據(jù)結(jié)構(gòu)JDK8

2019-11-11 14:51:19

Java數(shù)據(jù)結(jié)構(gòu)Properties

2022-12-02 09:13:28

SeataAT模式

2012-02-21 13:55:45

JavaScript

2022-10-31 09:00:24

Promise數(shù)組參數(shù)

2018-11-09 16:24:25

物聯(lián)網(wǎng)云計(jì)算云系統(tǒng)

2022-11-09 08:06:15

GreatSQLMGR模式

2009-11-18 13:30:37

Oracle Sequ

2009-11-30 16:46:29

學(xué)習(xí)Linux
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 国产精品av久久久久久久久久 | 一区二区三区免费 | 综合一区| 国产精品久久久久久久久动漫 | 亚洲视频国产视频 | 免费xxxx大片国产在线 | 狠狠操天天操 | 电影午夜精品一区二区三区 | 久久久久久久一区 | 久久免费视频观看 | 免费特黄视频 | 成人国内精品久久久久一区 | 成人国产午夜在线观看 | 一区二区三区免费在线观看 | 一区二区视频在线 | 久久久久久久久久久久一区二区 | 精品久久香蕉国产线看观看亚洲 | 天堂av资源 | 成人不卡视频 | 成人av一区二区三区 | 国产成人亚洲精品自产在线 | 中文字幕男人的天堂 | 亚洲精品一区二区三区 | 国产精品久久久久久久久久久免费看 | 国产精品视频一区二区三区四区国 | 毛片电影 | 亚洲一区二区三区在线播放 | 91视频在线观看 | 九九热视频这里只有精品 | av在线播放网 | 婷婷综合 | 久久日韩粉嫩一区二区三区 | 中文字幕一区二区三区在线观看 | 日韩久久综合网 | 日韩欧美在线观看 | 国产欧美在线 | 在线欧美一区二区 | 成人激情免费视频 | 精品啪啪 | 欧美韩一区二区 | www.亚洲一区二区三区 |