1. 程式人生 > >Java 執行緒的基本狀態和操作

Java 執行緒的基本狀態和操作

執行緒的幾種狀態

在Java當中,執行緒通常都有五種狀態,建立、就緒、執行、阻塞和死亡。

  • 第一是建立狀態。在生成執行緒物件,並沒有呼叫該物件的start方法,這是執行緒處於建立狀態。

  • 第二是就緒狀態。當呼叫了執行緒物件的start方法之後,該執行緒就進入了就緒狀態,
    但是此時執行緒排程程式還沒有把該執行緒設定為當前執行緒,此時處於就緒狀態。線上程執行之後,從等待或者睡眠中回來之後,也會處於就緒狀態。

  • 第三是執行狀態。執行緒排程程式將處於就緒狀態的執行緒設定為當前執行緒,此時執行緒就進入了執行狀態,開始執行run函式當中的程式碼。

  • 第四是阻塞狀態。執行緒正在執行的時候,被暫停,通常是為了等待某個時間的發生(比如說某項資源就緒)之後再繼續執行。
    sleep,suspend,wait等方法都可以導致執行緒阻塞。

  • 第五是死亡狀態。如果一個執行緒的run方法執行結束或者呼叫stop方法後,該執行緒就會死亡。
    對於已經死亡的執行緒,無法再使用start方法令其進入就緒。

操作執行緒的基本函式

wait()

當一個執行緒執行到wait()時, 他會進入到一個和該物件相關的等待池中,同時失去了物件的鎖機制,使得其他執行緒可以訪問.
使用者可以使用notify或notifyAll來喚醒當前等待池中的執行緒

Note:wait()和notify(),notifyAll()必須放在Synchronized Block中,否則會丟擲異常

notify()會隨機喚醒一個,一般使用notifyAll()就可以


/**
 * Created by yangtianrui on 17-1-1.
 * 執行緒的wait, sleep, join, yield方法
 */
public class WaitAndNotifyDemo {

    // 用於等待喚醒的物件
    private final static Object sLockObject = new Object();

    public static void main(String[] args) {
        waitAndNotifyAll();
    }


    private static void waitAndNotifyAll
() { System.out.println("主執行緒執行"); Thread thread = new WaitThread(); thread.start(); long startTime = System.currentTimeMillis(); try { synchronized (sLockObject) { System.out.println("主執行緒等待"); sLockObject.wait(); } } catch (InterruptedException e) { e.printStackTrace(); } long deltaTime = System.currentTimeMillis(); System.out.println("主執行緒等待了 " + (deltaTime - startTime)); } private static class WaitThread extends Thread { @Override public void run() { try { synchronized (sLockObject) { Thread.sleep(3000); // 釋放當前鎖 // 或者使用notifyAll(); sLockObject.notify(); } } catch (InterruptedException e) { e.printStackTrace(); } } } } /* 主執行緒執行 主執行緒等待 主執行緒等待了 3000 */

sleep()

該函式是sleep的靜態函式,作用是使呼叫執行緒進入睡眠狀態,因此他不能改變物件的鎖機制,所以當一個Synchronized塊中呼叫sleep(),
並不會使使當前執行緒釋放掉這個鎖,即使睡眠也持有這個物件鎖

join()

等待目標執行緒執行完成後再繼續執行


/**
 * Created by yangtianrui on 17-1-1.
 * Join() 阻塞當前呼叫Join()函式所在的執行緒,直到接收執行緒執行完畢後在執行
 */
public class JoinDemo {

    public static void main(String[] args) {
        Thread thread1 = new WorkerThread("worker-1");
        Thread thread2 = new WorkerThread("worker-2");
        thread1.start();
        System.out.println("啟動執行緒1");
        try {
            // worker1 的join函式後,主執行緒會一直阻塞到thread1執行完畢
            thread1.join();
            System.out.println("啟動執行緒2");
            thread2.start();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("主執行緒繼續執行");
    }


    private static class WorkerThread extends Thread {
        public WorkerThread(String name) {
            super(name);
        }

        @Override
        public void run() {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("work in  " + getName());
        }
    }
}

/*
    啟動執行緒1
    work in  worker-1
    啟動執行緒2
    work in  worker-2
    主執行緒繼續執行
*/

yield()

執行緒禮讓,目標執行緒由執行狀態轉換成就緒狀態,也就是讓出執行許可權,讓其他執行緒得以優先執行,但其他執行緒能否優先執行是未知的.

Note: 讓出執行時間並不是讓出持有的物件鎖


/**
 * Created by yangtianrui on 17-1-1.
 * yield()使該函式所在的執行緒讓出執行時間給其他已經就緒的執行緒
 * <p>
 * 讓出執行時間並不是讓出持有的物件鎖
 */

public class YieldDemo {


    public static void main(String[] args) {
        Thread thread1 = new YieldThread("thread-1");
        Thread thread2 = new YieldThread("thread-2");

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


    private static class YieldThread extends Thread {
        public YieldThread(String name) {
            super(name);
        }

        @Override
        public void run() {
            for (int i = 0; i < 50; i++) {
                System.out.println(getName() + " priority=" + getPriority() + " i=" + i);
                // 每兩次,執行一次yield()
                if (i % 2 == 0) {
                    Thread.yield();
                }
            }
        }
    }
}
/*
    到偶數時,會切換一次執行緒
    thread-1 priority=5 i=0
    thread-2 priority=5 i=0
    thread-1 priority=5 i=1
    thread-1 priority=5 i=2
    thread-2 priority=5 i=1
    thread-1 priority=5 i=3
    thread-2 priority=5 i=2
    thread-1 priority=5 i=4
    thread-2 priority=5 i=3
    thread-2 priority=5 i=4
    thread-1 priority=5 i=5
    thread-1 priority=5 i=6
    thread-2 priority=5 i=5
    thread-2 priority=5 i=6
    thread-1 priority=5 i=7
 */

Note: yield()呼叫之後,其他執行緒並不一定會搶佔到 執行時間

相關推薦

Java 執行基本狀態操作

執行緒的幾種狀態 在Java當中,執行緒通常都有五種狀態,建立、就緒、執行、阻塞和死亡。 第一是建立狀態。在生成執行緒物件,並沒有呼叫該物件的start方法,這是執行緒處於建立狀態。 第二是就緒狀態。當呼叫了執行緒物件的start方法之後,該執行緒就進

JVM學習之java執行實現&排程狀態轉換

1 謹慎使用java 多執行緒   如何提升效率:      使用java時推薦利用多執行緒處理一些操作絕大多數情況下確實能提高效率,提高效率的原理在哪裡呢,為什麼說絕大多說情況呢。        在CPU單核時代,我們知道某一時刻工作的執行緒只能是一條,那多執行緒為什

java中程序執行以及執行狀態方法

程序是cpu資源分配的最小單位,執行緒是cpu排程的最小單位。 一個程式至少有一個程序,一個程序至少有一個執行緒.  執行緒的劃分尺度小於程序,使得多執行緒程式的併發性高。 另外,程序在執行過程中擁有獨立的記憶體單元,而多個執行緒共享記憶體,從而極大地提高了程式的執行效率。

Java執行之semaphoreExchanger

Semaphore是Java執行緒的一個計數訊號量。我們可用於多執行緒的併發訪問控制。 就像我們常見的執行緒池,資料庫連線池就可以使用Semaphore進行邏輯的實現。Semaphore中我們就介紹兩個最常用的兩個方法。 acquire() 從Semaphore獲取許可,如果計數不小於0

java執行池ThreadPoolExecutor阻塞佇列BlockingQueue,Executor, ExecutorService

ThreadPoolExecutor 引數最全的建構函式 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,

java執行狀態轉換

執行緒狀態圖 說明: 執行緒共包括以下5種狀態。 1. 新建狀態(New)         : 執行緒物件被建立後,就進入了新建狀態。例如,Thread thread = new Thread()。 2. 就緒狀態(Runnable): 也被稱為“可執行狀態”。執行

java 執行基本知識(一)

import java.lang.Thread; 1.建立執行緒 Thread th=new Thread(); ps: Thread th=new Thread() { public void run() { System.out.println("run方法");

java執行狀態變換

下面將會針這張圖對執行緒的狀態轉換來做解釋 在作業系統的課程中把執行緒大致分為了3個狀態 1.就緒狀態(執行緒對資源上鎖,但未分配時間片,等待cpu分配,隨時可以執行) 2.執行狀態(執行緒對資源上鎖,並擁有了時間片,正在執行中) 3.阻塞狀態(在執行狀態下缺失了某種資源導致執行暫

Linux下Java執行詳細監控其dump的分析使用----分析Java效能瓶頸[張振華-Jack]

作者:張振華(Jack) 這裡對linux下、sun(oracle) JDK的執行緒資源佔用問題的查詢步驟做一個小結; linux環境下,當發現java程序佔用CPU資源很高,且又要想更進一步

java執行中yield()join()的區別

package test.core.threads; public class JoinExample { public static void main(String[] args) throws InterruptedException { Thread t = new Thr

Java執行】CallableFuture

Future模式 Future介面是Java執行緒Future模式的實現,可以來進行非同步計算。 Future模式可以這樣來描述: 我有一個任務,提交給了Future,Future替我完成這個任務。期間我自己可以去做任何想做的事情。一段時間之後,我就便可以從Future那兒

java執行中CallbleFuture的使用

     Callable是java.util.concurrent包中一個介面,Callable 介面類似於Runnable,兩者都是為那些其例項可能被另一個執行緒執行的類設計的。但是Runnable 不會返回結果,並且無法丟擲經過檢查的異常。此介面中就聲明瞭一個方法c

Java——執行的同步通訊

執行緒安全是指多個執行緒訪問同一程式碼,不會產生不確定的結果; 執行緒同步: 為了避免多執行緒在共享資源時發生衝突,所以 要線上程使用該資源時,就為執行緒上一把“鎖”,第一個訪問資源的執行緒為資源上鎖,其他執行緒若想訪問該資源,則必須等待解鎖為止,解鎖的同時,另

Java執行之生產者消費者

Java執行緒的作用是可以使一個程式中的執行緒可以並行執行,這樣可以大大縮短程式執行所需要的時間。但是當這些執行緒都對同一個變數或者記憶體進行操作的時候如果不加以控制就會出現許多不可預見的錯誤,而且在不同時間執行也會產生不同的錯誤,並且很難排查。 對於生產者和消

java執行狀態

NEW 狀態是指執行緒剛建立, 尚未啟動 RUNNABLE 狀態是執行緒正在正常執行中, 當然可能會有某種耗時計算/IO等待的操作/CPU時間片切換等, 這個狀態下發生的等待一般是其他系統資源, 而不是鎖, Sleep等 BLOCKED 這個狀態下, 是在

Java執行協作--生產者消費者模式

    生產者消費者模式是執行緒協作的經典應用,主要由具體產品類,容器類,生產者執行緒,消費者執行緒組成。具體表現形式為生產者執行緒生產產品往容器裡放置,當容器滿的時候,生產執行緒呼叫wait方法,使當前執行緒阻塞,而此時消費者執行緒在不斷的消費容器裡的產品,同時呼叫noti

Java執行的同步通訊

           當兩個或兩個以上的執行緒需要共享資源,它們需要某種方法來確定資源在某一刻僅被一個執行緒佔用。達到此目的的過程叫做同步(synchronization)。像你所看到的,Java為此

Java--執行的分類生命週期

Java中的執行緒分為兩類: 一種是守護執行緒 一種是使用者執行緒 它們在幾乎的每個方面都是相同的,唯一的區別是判斷JVM何時離開 守護執行緒是用來服務使用者執行緒的,通過在start()方法前呼叫thread.setDaemon(true)可以把一個使用者執行緒變成一個守

Java 執行的suspend()stop()不安全的原因

一、suspend()不安全的原因        在Java中執行緒的suspend()方法用於懸掛起一個執行緒,但是它之前持有的鎖卻沒有釋放。那麼其他等待該鎖的執行緒就會一直等待,直到該執行緒被re

Java執行池原理使用

為什麼要用執行緒池? 諸如 Web 伺服器、資料庫伺服器、檔案伺服器或郵件伺服器之類的許多伺服器應用程式都面向處理來自某些遠端來源的大量短小的任務。請求以某種方式到達伺服器,這種方式可能是通過網路協議(例如 HTTP、FTP 或 POP)、通過 JMS 佇列或者可能通過