1. 程式人生 > 實用技巧 >建立並啟動執行緒

建立並啟動執行緒

建立並啟動執行緒

場景:

假如我現在需要在讀資料庫的同時往磁盤裡寫資料,這個要怎麼做呢?

package com.thread.thread01;

/**
 * @program: ThreadDemo
 * @description: 建立並啟動執行緒
 * @author: [email protected]
 * @create: 2020-08-26 09:56
 */
public class TryConcurrency {
    public static void main(String[] args) {
        readFromDataBase();
        writeDataToFile();
    }
    /**
     * 讀資料
     */
    private static void readFromDataBase() {
        // read data from database and handle it
        try {
            println("Begin read data from db.");
            Thread.sleep(1000 * 1L);
            println("Read data done and start handle it.");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        println("The data handle finish and successfully.");
    }

    /**
     * 寫資料
     */
    private static void writeDataToFile() {
        // write data to file
        try {
            println("Begin write data to file.");
            Thread.sleep(1000 * 1L);
            println("Write data done and start handle it.");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        println("The data handle finish and successfully.");
    }

    private static void println(String message) {
        System.out.println(message);
    }
}

執行效果如下:

可以看到這兩個方法其實是順序執行的不是交替執行的,接下來我們開啟JDK的文件,找到Thread類:

可以看到在JVM啟動的時候其實有一個非守護的main執行緒來啟動我們的main函式。

為了驗證這個,我們來建立一個sleep的執行緒,我們來使用jconsole工具來檢視一下:

public static void main(String[] args) {
    try {
        Thread.sleep(1000 * 100L);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

可以看到是有一個main執行緒存在的,他是waiting狀態,所以,我們可以在main方法裡,再建立一個執行緒,讓這兩個執行緒交替列印一下數字:

public static void main(String[] args) {
       Thread t1 = new Thread("Custom-Thread") {
            @Override
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    println("Task i=>" + i);
                    try {
                        Thread.sleep(1000 * 1L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        t1.start();
        for (int j = 0; j < 1000; j++) {
            try {
                Thread.sleep(900 * 1L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            println("Task j=>" + j);
        }
    }

效果如下:

可以看到這兩個執行緒已經交替執行了。

再用jconsole檢視一下:

把main執行緒的迴圈註釋掉:

public static void main(String[] args) {
    Thread t1 = new Thread("Custom-Thread") {
        @Override
        public void run() {
            for (int i = 0; i < 1000; i++) {
                println("Task i=>" + i);
                try {
                    Thread.sleep(1000 * 1L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };
    t1.start();
    /*for (int j = 0; j < 1000; j++) {
        try {
            Thread.sleep(900 * 1L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        println("Task j=>" + j);
    }*/
}

再用jconsole檢視一下:

main執行緒已經退出了。

還有一個容易忽略的問題:

顯然不是,因為執行結果直接就出來了:

這裡涉及到執行緒的生命週期了,後續再深入學習,這裡只提一下。

現在再思考之前提出的問題:假如我現在需要在讀資料庫的同時往磁盤裡寫資料,這個要怎麼做呢?

/**
 * @program: ThreadDemo
 * @description: 建立並啟動執行緒
 * @author: [email protected]
 * @create: 2020-08-26 09:56
 */
public class TryConcurrency {
    public static void main(String[] args) {
        new Thread("READ-Thread") {
            @Override
            public void run() {
                readFromDataBase();
            }
        }.start();
        new Thread("WRITE-Thread") {
            @Override
            public void run() {
                writeDataToFile();
            }
        }.start();

    }

    /**
     * 讀資料
     */
    private static void readFromDataBase() {
        // read data from database and handle it
        try {
            println("Begin read data from db.");
            Thread.sleep(1000 * 1L);
            println("Read data done and start handle it.");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        println("The data handle finish and successfully.");
    }

    /**
     * 寫資料
     */
    private static void writeDataToFile() {
        // write data to file
        try {
            println("Begin write data to file.");
            Thread.sleep(1000 * 1L);
            println("Write data done and start handle it.");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        println("The data handle finish and successfully.");
    }

    private static void println(String message) {
        System.out.println(message);
    }
}

執行效果如下:

可以看到已經交替執行了。

再用jconsole檢視一下:

這樣我們就簡單的實現了讀資料庫的同時往磁盤裡寫資料的操作。當然雖然沒真正的度資料庫和往磁盤裡寫資料,但是,主要還是理解這個交替執行的過程。