最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java多線程 兩階段終止模式Two-Phase Termination Patter

 更新時間:2021年10月28日 14:47:22   作者:冬日毛毛雨  
這篇文章主要介紹了Java多線程 兩階段終止模式Two-Phase Termination Patter,該模式有兩個角色,分別是Terminator,終止者,負責接收終止請求,執(zhí)行終止處理,處理完成后再終止自己。TerminationRequester終止請求發(fā)出者,用來向Terminator發(fā)出終止請求,需要的朋友可以參考一下

1、兩階段終止模式介紹

有時候,我們希望提前結束線程,但安全可靠地停止線程,并不是一件容易的事情,如果立即停止線程,會使共享的數(shù)據(jù)結構處于不一致的狀態(tài),如目前已經(jīng)廢棄使用的Thread類的stop方法(它會使線程在拋出java.lang.ThreadDeath之后終止線程,即使是在執(zhí)行synchronized方法的時候)。更好的做法是執(zhí)行完終止處理,再終止線程,即Two-phase Termination,兩階段終止模式。

該模式有兩個角色:

  • Terminator,終止者,負責接收終止請求,執(zhí)行終止處理,處理完成后再終止自己。
  • TerminationRequester:終止請求發(fā)出者,用來向Terminator發(fā)出終止請求。

2、Terminator代碼演示

該模式示例代碼如下:

public class CounterIncrement extends Thread {

    private volatile boolean terminated = false;

    private int counter = 0;

    private Random random = new Random(System.currentTimeMillis());
    @Override
    public void run() {

        try {
            while (!terminated) {
                System.out.println(Thread.currentThread().getName()+" "+counter++);
                Thread.sleep(random.nextInt(1000));
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            this.clean();
        }
    }

    private void clean() {
        System.out.println("do some clean work for the second phase,current counter "+counter);

    }

    public void close() {
        this.terminated = true;
        this.interrupt();
    }
}

3、TerminationRequester

public class CounterTest {
    public static void main(String[] args) throws InterruptedException {
        CounterIncrement counterIncrement = new CounterIncrement();
        counterIncrement.start();

        Thread.sleep(15_000L);
        //主動清理
        counterIncrement.close();
    }
}

這段代碼可以看出實現(xiàn)兩階段終止模式必須注意的是:

使用線程停止標志和interrupt方法,兩者缺一不可

  public void close() {
        this.terminated = true;
        this.interrupt();
    }

這里使用了terminated作為線程停止標志,變量采用volatile修飾,避免了使用顯式鎖的開銷,又保證了內存可見性。線程run方法會檢查terminated屬性,如果屬性為true,就停止線程,但線程可能調用了阻塞方法,處于wait狀態(tài),任務也就可能永遠不會檢查terminated標志;線程也有可能處于sleep()狀態(tài),等sleep時間過后再執(zhí)行終止狀態(tài),程序的響應性就下降了。你可以把方法改成如下運行,線程停止明顯變慢了許多:

  public void close() {
        terminated = true;
  }

4、模擬客戶端或者服務端都可能終止服務的例子

public class AppServer extends Thread {

    private static final int DEFAULT_PORT = 12722;
    private final static ExecutorService executor = Executors.newFixedThreadPool(10);
    private int port;
    private volatile boolean start = true;
    private List<ClientHandler> clientHandlers = new ArrayList<>();
    private ServerSocket server;

    public AppServer() {
        this(DEFAULT_PORT);
    }

    public AppServer(int port) {
        this.port = port;
    }

    @Override
    public void run() {
        try {
            server = new ServerSocket(port);
            while (start) {
                Socket client = server.accept();
                ClientHandler clientHandler = new ClientHandler(client);
                executor.submit(clientHandler);
                this.clientHandlers.add(clientHandler);
            }

        } catch (IOException e) {
            //throw new RuntimeException();
        } finally {
            this.dispose();
        }
    }

    public void dispose() {
        System.out.println("dispose");
        this.clientHandlers.stream().forEach(ClientHandler::stop);
        this.executor.shutdown();
    }

    public void shutdown() throws IOException {
        this.start = false;
        this.interrupt();
        this.server.close();
    }
}

public class ClientHandler implements Runnable {

    private final Socket socket;

    private volatile boolean running = true;

    public ClientHandler(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {


        try (InputStream inputStream = socket.getInputStream();
             OutputStream outputStream = socket.getOutputStream();
             BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
             PrintWriter printWriter = new PrintWriter(outputStream)) {
            while (running) {
                String message = br.readLine();
                if (message == null) {
                    break;
                }
                System.out.println("Come from client >" + message);
                printWriter.write("echo " + message+"\n");
                printWriter.flush();
            }
        } catch (IOException e) {
            //自動關閉的時候 將running
            this.running = false;
        }finally {
            this.stop();
        }

    }

    public void stop() {
        if (!running) {
            return;
        }
        this.running = false;
        try {
            this.socket.close();

        } catch (IOException e) {

        }
    }
}

public class AppServerClient {
    public static void main(String[] args) throws InterruptedException, IOException {
        AppServer server = new AppServer(12135);
        server.start();

        Thread.sleep(20_000L);
        server.shutdown();
    }
}

5、mac telnet模擬客戶端輸入

bogon:~ kpioneer$ telnet localhost 12135
Trying ::1...
Connected to localhost.
Escape character is '^]'.
hello 
echo hello 
I love you
echo I love you
Connection closed by foreign host.

服務端輸出:

Come from client >hello
Come from client >I love you
dispose

總結:

可以看到,在子類使用兩階段終止模式時,其只需要實現(xiàn)各自所需要執(zhí)行的任務,并且更新當前任務的數(shù)量即可。在某些情況下,當前任務的數(shù)量也可以不進行更新,比如在進行終止時,不關心當前剩余多少任務需要執(zhí)行。

到此這篇關于Java多線程 兩階段終止模式Two-Phase Termination Patter的文章就介紹到這了,更多相關Java多線程 兩階段終止模式內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • SpringBoot+Email發(fā)送郵件的實現(xiàn)示例

    SpringBoot+Email發(fā)送郵件的實現(xiàn)示例

    Spring?Boot提供了簡單而強大的郵件發(fā)送功能,本文主要介紹了SpringBoot+Email發(fā)送郵件的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • IDEA創(chuàng)建Java項目文件并運行教程解析

    IDEA創(chuàng)建Java項目文件并運行教程解析

    這篇文章主要介紹了IDEA創(chuàng)建Java項目文件并運行教程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-11-11
  • SpringBoot3文件管理操作方法

    SpringBoot3文件管理操作方法

    這篇文章主要介紹了SpringBoot3文件管理,本文案例只圍繞普通文件和Excel兩種類型進行代碼實現(xiàn),包括工程搭建、上傳下載操作,需要的朋友可以參考下
    2023-08-08
  • Eclipse連接Mysql數(shù)據(jù)庫操作總結

    Eclipse連接Mysql數(shù)據(jù)庫操作總結

    這篇文章主要介紹了Eclipse連接Mysql數(shù)據(jù)庫操作總結的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-08-08
  • Nacos設置為windows自啟動服務的步驟詳解

    Nacos設置為windows自啟動服務的步驟詳解

    這篇文章給大家介紹了Nacos設置為windows自啟動服務的操作步驟,文中通過代碼示例和圖文結合講解的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2023-12-12
  • Java中字符串與日期轉換常見方法總結

    Java中字符串與日期轉換常見方法總結

    這篇文章主要給大家介紹了關于Java中字符串與日期轉換常見方法的相關資料,在Java編程中經(jīng)常需要將字符串表示的日期轉換為日期對象進行處理,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2023-11-11
  • IDEA使用學生郵箱無法注冊問題:JetBrains Account connection error: 拒絕連接

    IDEA使用學生郵箱無法注冊問題:JetBrains Account connection error: 拒絕連接

    這篇文章主要介紹了IDEA使用學生郵箱無法注冊問題:JetBrains Account connection error: 拒絕連接,文中通過圖文及示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-07-07
  • Java異常Exception詳細講解

    Java異常Exception詳細講解

    異常就是不正常,比如當我們身體出現(xiàn)了異常我們會根據(jù)身體情況選擇喝開水、吃藥、看病、等?異常處理方法。?java異常處理機制是我們java語言使用異常處理機制為程序提供了錯誤處理的能力,程序出現(xiàn)的錯誤,程序可以安全的退出,以保證程序正常的運行等
    2022-07-07
  • 詳解eclipse項目中的.classpath文件原理

    詳解eclipse項目中的.classpath文件原理

    這篇文章介紹了eclipse項目中的.classpath文件的原理,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-12-12
  • 基于Spring p標簽和c標簽注入方式

    基于Spring p標簽和c標簽注入方式

    這篇文章主要介紹了Spring p標簽和c標簽注入方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09

最新評論

谷城县| 延庆县| 周口市| 融水| 马关县| 清徐县| 偏关县| 靖边县| 广丰县| 芜湖市| 卫辉市| 望奎县| 河北省| 新津县| 商河县| 邓州市| 五原县| 上思县| 镇赉县| 麻江县| 分宜县| 东乡族自治县| 平乐县| 远安县| 南开区| 宁乡县| 阜康市| 柯坪县| 舟曲县| 洛扎县| 额济纳旗| 蓬安县| 万荣县| 大丰市| 通许县| 齐齐哈尔市| 华安县| 斗六市| 漳浦县| 周宁县| 宁海县|