Java_多線程_創建多線程的4種方式 與 線程狀態

 

參考文章:

1.創建多線程有四種方式

https://blog.csdn.net/YTREE_BJ/article/details/92761104

 

2.創建多線程的4種方式

https://www.cnblogs.com/zhou-test/p/9811771.html

 

3.線程的BLOCK、WAITING、TIMED_WAITING狀態

https://blog.csdn.net/weixin_41485592/article/details/103958333

 

線程的狀態

在進行多線程編程之前,要先知道線程都有哪幾種狀態。

線程的狀態在 java.lang.Thread.State 有定義:

/**
     * A thread state.  A thread can be in one of the following states:
     * <ul>
     * <li>{@link #NEW}<br>
     *     A thread that has not yet started is in this state.
     *     </li>
     * <li>{@link #RUNNABLE}<br>
     *     A thread executing in the Java virtual machine is in this state.
     *     </li>
     * <li>{@link #BLOCKED}<br>
     *     A thread that is blocked waiting for a monitor lock
     *     is in this state.
     *     </li>
     * <li>{@link #WAITING}<br>
     *     A thread that is waiting indefinitely for another thread to
     *     perform a particular action is in this state.
     *     </li>
     * <li>{@link #TIMED_WAITING}<br>
     *     A thread that is waiting for another thread to perform an action
     *     for up to a specified waiting time is in this state.
     *     </li>
     * <li>{@link #TERMINATED}<br>
     *     A thread that has exited is in this state.
     *     </li>
     * </ul>
     *
     * <p>
     * A thread can be in only one state at a given point in time.
     * These states are virtual machine states which do not reflect
     * any operating system thread states.
     *
     * @since   1.5
     * @see #getState
     */
    public enum State {
        /**
         * Thread state for a thread which has not yet started.
         */
        NEW,

        /**
         * Thread state for a runnable thread.  A thread in the runnable
         * state is executing in the Java virtual machine but it may
         * be waiting for other resources from the operating system
         * such as processor.
         */
        RUNNABLE,

        /**
         * Thread state for a thread blocked waiting for a monitor lock.
         * A thread in the blocked state is waiting for a monitor lock
         * to enter a synchronized block/method or
         * reenter a synchronized block/method after calling
         * {@link Object#wait() Object.wait}.
         */
        BLOCKED,

        /**
         * Thread state for a waiting thread.
         * A thread is in the waiting state due to calling one of the
         * following methods:
         * <ul>
         *   <li>{@link Object#wait() Object.wait} with no timeout</li>
         *   <li>{@link #join() Thread.join} with no timeout</li>
         *   <li>{@link LockSupport#park() LockSupport.park}</li>
         * </ul>
         *
         * <p>A thread in the waiting state is waiting for another thread to
         * perform a particular action.
         *
         * For example, a thread that has called <tt>Object.wait()</tt>
         * on an object is waiting for another thread to call
         * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
         * that object. A thread that has called <tt>Thread.join()</tt>
         * is waiting for a specified thread to terminate.
         */
        WAITING,

        /**
         * Thread state for a waiting thread with a specified waiting time.
         * A thread is in the timed waiting state due to calling one of
         * the following methods with a specified positive waiting time:
         * <ul>
         *   <li>{@link #sleep Thread.sleep}</li>
         *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
         *   <li>{@link #join(long) Thread.join} with timeout</li>
         *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
         *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
         * </ul>
         */
        TIMED_WAITING,

        /**
         * Thread state for a terminated thread.
         * The thread has completed execution.
         */
        TERMINATED;
    }
 <li>{@link #NEW}<br>
*     A thread that has not yet started is in this state.
*     </li>
  創建後尚未啓動的線程處於這種狀態


* <li>{@link #RUNNABLE}<br>
*     A thread executing in the Java virtual machine is in this state.
*     </li>
  Runable包括了操作系統線程狀態的Running和Ready,也就是處於此狀態的線程有可能正在執行,也有可能正在等待着CPU爲它分配執行時間。


* <li>{@link #BLOCKED}<br>
*     A thread that is blocked waiting for a monitor lock
*     is in this state.
*     </li>
  線程被阻塞了,“阻塞狀態”與”等待狀態“的區別是:”阻塞狀態“在等待着獲取到一個排他鎖,這個時間將在另外一個線程放棄這個鎖的時候發生;而”等待狀態“則是在等待一段時間或者喚醒動作的發生。在程序等待進入同步區域的時候,線程將進入這種狀態。



* <li>{@link #WAITING}<br>
*     A thread that is waiting indefinitely for another thread to
*     perform a particular action is in this state.
*     </li>
  處於這種狀態的線程不會被分配CPU執行時間。
  等待狀態又分爲無限期等待和有限期等待,WAITING 爲無限期等待
  處於無限期等待的線程需要被其他線程顯示地喚醒,沒有設置Timeout參數的Object.wait()、沒有設置Timeout參數的Thread.join()方法都會使線程進入無限期等待狀態;

線程處於WAITING狀態的場景。

  • 調用Object對象的wait方法,但沒有指定超時值。
  • 調用Thread對象的join方法,但沒有指定超時值。
  • 調用LockSupport對象的park方法。

* <li>{@link #TIMED_WAITING}<br>
*     A thread that is waiting for another thread to perform an action
*     for up to a specified waiting time is in this state.
*     </li>
  當處於一個給定的等待時間時候,線程處於這種狀態 TIMED_WAITING
  有限期等待狀態無須等待被其他線程顯示地喚醒,在一定時間之後它們會由系統自動喚醒,Thread.sleep()、設置了Timeout參數的Object.wait()、設置了Timeout參數的Thread.join()方法都會使線程進入有限期等待狀態。

線程處於TIMED_WAITING狀態的場景。

調用Thread.sleep方法。
調用Object對象的wait方法,指定超時值。
調用Thread對象的join方法,指定超時值。
調用LockSupport對象的parkNanos方法。
調用LockSupport對象的parkUntil方法。



* <li>{@link #TERMINATED}<br>
*     A thread that has exited is in this state.
*     </li>

  已終止線程的線程狀態,線程已經結束執行。

 

 

 

線程狀態間的切換

既然有那麼多的線程狀態,它們之間的狀態轉換如下圖所示

 

線程間同步的方法

線程有4中同步方法,分別爲wait()、sleep()、notify()和notifyAll()。

wait():使線程處於一種等待狀態,釋放所持有的對象鎖。

sleep():使一個正在運行的線程處於睡眠狀態,是一個靜態方法,調用它時要捕獲InterruptedException異常,不釋放對象鎖。

notify():喚醒一個正在等待狀態的線程。注意調用此方法時,並不能確切知道喚醒的是哪一個等待狀態的線程,是由JVM來決定喚醒哪個線程,不是由線程優先級決定的。

notifyAll():喚醒所有等待狀態的線程,注意並不是給所有喚醒線程一個對象鎖,而是讓它們競爭。

 

Java 創建線程的4種方式 :

  1. 繼承Thread類創建多線程
  2. 實現Runnable接口創建多線程
  3. 實現Callable接口通過FutureTask包裝器來創建Thread多線程
  4. 使用ExecutorService、Callable、Future實現有返回結果的線程。

 

繼承Thread類創建多線程

代碼如下:繼承Thread類

package com.dazhi.thread.multithread;

/**
 * 多線程創建,繼承
 * @author dazhi
 */
public class MyThread extends Thread{

    @Override
    public void run() {
        for (int i=0; i<10; i++) {
            System.out.println(Thread.currentThread().getName() +":"+ i);
        }
    }

    public static void main(String[] args) throws InterruptedException {

        MyThread thread1 = new MyThread();
        MyThread thread2 = new MyThread();
        MyThread thread3 = new MyThread();

        thread1.start();
        thread2.start();
        thread3.start();

    }
}

 

實現Runnable接口創建多線程


實現Runnable接口

package com.dazhi.thread.multithread;

/**
 * 多線程創建, 實現Runnable
 * @author dazhi
 */
public class MyRunnable implements Runnable {

    @Override
    public void run() {
        for (int i=0; i<10; i++) {
            System.out.println(Thread.currentThread().getName() +":"+ i);
        }
    }

    public static void main(String[] args) {

        MyRunnable myRunnable = new MyRunnable();
        Thread thread1 = new Thread(myRunnable, "thread1");
        Thread thread2 = new Thread(myRunnable, "thread2");
        Thread thread3 = new Thread(myRunnable, "thread3");

        thread1.start();
        thread2.start();
        thread3.start();
    }
}

 

實現Callable接口通過FutureTask包裝器來創建Thread多線程


實現Callable

package thread.multi;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

/**
 * Created by szh on 2020/6/15.
 *
 * @author szh
 */
public class CallableThread implements Callable<String> {

    @Override
    public String call() throws Exception {

        Thread.sleep(10 * 1000);

        return "Just do it";
    }

    public static void main(String[] args) throws Exception {

        CallableThread callableThread = new CallableThread();
        FutureTask<String> stringFuture = new FutureTask<String>(callableThread);
        Thread a = new Thread(stringFuture);
        a.start();

        System.out.println(stringFuture.get());
    }
}

// 運行結果
Just do it

注意  get 會阻塞線程的運行,直到得到返回結果!!

 

 

 

使用ExecutorService、Callable、Future實現有返回結果的線程。


 

package com.dazhi.thread.multithread;

import java.util.concurrent.*;

/**
 * 多線程創建, ExecutorService + Callable + Future
 * @author dazhi
 */
public class MyExecutors {

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        // 不提倡的方式創建線程池方式。爲了方便就這樣寫了
        ExecutorService executorService = Executors.newFixedThreadPool(5);

        Future<Integer> submit = executorService.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return 1234;
            }
        });
        executorService.shutdown();
        System.out.println(submit.get());
    }
}

// 運行結果
1234

Process finished with exit code 0

// 不提倡創建線程池的原因

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章