1. 程式人生 > >多執行緒常用的幾個方法彙總

多執行緒常用的幾個方法彙總

最近學習併發程式設計遇到不少問題,就順手總結了有關多執行緒的幾個常用的方法

sleep()

sleep()方法屬於Thread類,主要的作用是讓當前執行緒停止執行,把cpu讓給其他執行緒執行,但不會釋放物件鎖和監控的狀態,到了指定時間後執行緒又會自動恢復執行狀態

注意:執行緒睡眠到期自動甦醒,並返回到可執行狀態,不是執行狀態。sleep()中指定的時間是執行緒不會執行的最短時間。因此,sleep()方法不能保證該執行緒睡眠到期後就開始執行

  • 另外

    • Thread.sleep()方法是一個靜態方法

    • Java有兩種sleep方法,一個只有一個毫秒引數,另一個有毫秒和納秒
      個引數第三代

sleep(long millis)

or

sleep(long millis, int nanos)

1//此try語句塊放在run方法內
2try {
3            Thread.sleep(1000);
4       } catch (InterruptedException e) {
5            // TODO 自動生成的 catch 塊
6            e.printStackTrace();
7       }

wait() notify()

wait()屬於Object類,與sleep()的區別是當前執行緒會釋放鎖,進入等待此物件的等待鎖定池。比方說,執行緒A呼叫Obj.wait(),執行緒A就會停止執行,而轉為等待狀態。至於等待多長時間? 那就看其他執行緒是否呼叫Obj.notify().其優勢顯而易見,成為多個執行緒之間進行通訊的有手段!

注意:它必須包含在Synchronzied語句中,無論是wait()還是notify()都需要首先獲得目標的物件的一個監視器

  • 先來解釋一下 "Synchronzied" 
    是一種同步鎖。作用是實現執行緒間同步,對同步的程式碼加鎖,使得每一次,只能有一執行緒進入同步塊,從而保證執行緒間的安全性

它修飾的物件有以下幾種:

  • 修飾一個程式碼塊,被修飾的程式碼塊稱為同步語句塊,其作用的範圍是大括號{}括起來的部分,進入同步程式碼前要獲得給定物件的鎖

  • 修飾一個例項方法,進入同步程式碼前要獲得當前例項的鎖

  • 修飾一個靜態方法,進入同步程式碼前要獲得當前類的鎖

先給大家一個例子:

 1public class SimpleWN
{
2    public static int count=0;
3    public static class one implements Runnable{
4        @Override
5        public void run() {
6            for (int i = 0; i < 100; i++) {
7                synchronized (this) {
8                    count++;
9                }
10            }                          
11        }  
12    }
13    public static void main(String[] args) throws InterruptedException {
14        Thread t1=new Thread(new one());
15        Thread t2=new Thread(new one());
16        t1.start();
17        t2.start();
18        t1.join();
19        t2.join();
20        System.out.println(count);
21    }
22}

不知道大家看出這段程式碼有一個嚴重錯誤。程式碼17,18行,兩個執行緒例項的不是同一個物件,這也意味兩個執行緒使用的是兩把不同的鎖,沒法保證同步。多執行幾次就會發現有時候結果並不是200

更正做法:

1    one oo=new one();
2    Thread t1=new Thread(oo);
3    Thread t2=new Thread(oo);

舉例說明程式中應用wait() 和 notify():

 1public class SimpleWN {
2    final static Object object=new Object();
3    public static class one extends Thread{
4        @Override
5        public void run() {
6            synchronized (object) {
7                System.out.println("T1 開始");
8                try {
9                    System.out.println("T1 等待");
10                    object.wait();
11                } catch (InterruptedException e) {
12                    e.printStackTrace();
13                }
14                System.out.println("T1 結束");
15            }                  
16        }  
17    }
18    public static class two extends Thread{
19        @Override
20        public void run() {
21            synchronized (object) {
22                System.out.println("T2 開始");
23                System.out.println("釋放一個執行緒");
24                object.notify();
25                System.out.println("T2 結束");
26            }                  
27        }  
28    }
29    public static void main(String[] args) throws InterruptedException {
30        Thread t1=new one();
31        Thread t2=new two();
32        t1.start();
33        t2.start();
34        t1.join();
35        t2.join();
36    }
37}

執行結果:

1T1 開始
2T1 等待
3T2 開始
4釋放一個執行緒
5T2 結束
6T1 結束

join()

在某些情況下,子執行緒需要進行大量的耗時運算,主執行緒可能會在子執行緒執行結束之前結束,但是如果主執行緒又需要用到子執行緒的結果,換句話說,就是主執行緒需要在子執行緒執行之後再結束。這就需要用到join()方法

 1public class BigJoin {
2    public static int count;
3    public static class AddThread implements Runnable{
4        @Override
5        public void run() {
6            for (int i = 0; i < 1000000000; i++) {
7                count++;
8            }  
9        }  
10    }
11    public static void main(String[] args) throws InterruptedException {
12        // TODO 自動生成的方法存根
13        AddThread addThread=new AddThread();
14        Thread t1=new Thread(addThread);
15        t1.start();
16        t1.join();
17        System.out.println(count);
18    }
19}

yield()

中文意思:放棄,屈服
一個執行緒呼叫yield()意味著告訴虛擬機器自己非常樂於助人,可以把自己的位置讓給其他執行緒(這只是暗示,並不表絕對)。但得注意,讓出cpu並不代表當前執行緒不執行了。當前執行緒讓出cpu後,還會進行cpu資源的爭奪,但是能不能再次分配到,就不一定了

 1public class SimpleYield extends Thread{
2    String name=null;
3    public  SimpleYield(String name) {
4        super(name);
5    }
6    @Override
7    public void run() {
8        // TODO 自動生成的方法存根
9        for(int i=1;i<=10;i++){
10            System.out.println(this.getName()+i);
11            if(i==5){
12                this.yield();
13            }
14        }
15    }
16    public static void main(String[] args) throws InterruptedException {
17        SimpleYield t1=new SimpleYield("小花");
18        SimpleYield t2=new SimpleYield("小草");
19        t1.start();
20        t2.start();
21    }
22}

執行結果:這只是其中一種結果,執行緒(小花)的執行到2時把cpu讓給執行緒(小草)並執行,接下來-執行緒(小草)的執行到2時把cpu讓給執行緒(小花)並執行

1小花1
2小花2
3小草1
4小草2
5小花3
6小花4
7小草3
8小草4
長按識別二維碼關注

相關推薦

關於執行問題(面試小問題,Java篇)

面試官想考考我多執行緒方面的問題。 1、請說下執行緒與程序的關係。 答:《作業系統》中是這樣說的 (1)一個執行緒只能屬於一個程序,而一個程序可以有多個執行緒,但至少有一個執行緒。執行緒是作業系統可識別的最小執行和排程單位。 (2)資源分配給程序,同一程序的所有執行緒共享

建立執行方法

多執行緒有幾種實現方法,分別是什麼?(建立執行緒的幾種方式) 多執行緒有三種實現方法: 1、繼承Thread類,重寫run()方法。然後直接new這個物件的例項,建立一個執行緒的例項,再呼叫start()方法啟動執行緒。(其實本質上Thread是實現了Runnabl

建立執行方法?如何建立執行

多執行緒有幾種實現方法? 多執行緒實現又3種方法,其中前兩中是常用的方法,推薦第二種方法,一個類應該在其修改或者加強是才繼承 1.繼承Thread類,重寫run()方法,例項化該類,呼叫執行緒start()方法 (1)自定義類,繼承Thread類,重寫run()方法 (2

Python併發程式設計之建立執行方法

今天的內容會比較基礎,主要是為了讓新手也能無障礙地閱讀,所以還是要再鞏固下基礎。學完了基礎,你們也就能很順暢地跟著我的思路理解以後的文章。本文目錄學會使用函式建立多執行緒學會使用類建立多執行緒多執行緒:必學函式講解經過總結,Python建立多執行緒主要有如下兩種方法:函式類接

執行常用方法彙總

最近學習併發程式設計遇到不少問題,就順手總結了有關多執行緒的幾個常用的方法sleep()sleep()方法屬於Thread類,主要的作用是讓當前執行緒停止執行,把cpu讓給其他執行緒執行,但不會釋放物件鎖和監控的狀態,到了指定時間後執行緒又會自動恢復執行狀態注意:執行緒睡眠到期自動甦醒,並返回到可執行狀態,不

整理 C# 執行常用物件和方法

Thread 幾個中要的方法     Sleep(int):靜態方法,暫停當前執行緒指定的毫秒數     Abort():通常使用該方法來終止一個執行緒  ,Thread.ResetAbort() 可以恢復終止的執行緒     Suspend():不是終止未完成的執行緒,它僅

執行常用操作方法(sleep、yield、join)

執行緒的命名與取得 執行緒的命名: 通過構造方法在建立執行緒時設定執行緒名稱 直接繼承Thread類: public Thread (String name); Runable或者Callable介面實現多執行緒: public Thread (Run

執行(一):建立執行方法

概括來說就是兩種:1、繼承Thread類,重寫run方法,然後start。不推薦這種,因為java的單繼承特性。 2、Thread類的建構函式中可以接受Runnable任務,所以只要是Runnable例項就可以作為引數給Thread 一般有兩種建立Runnable例項的方法(1)實現Runn

java執行種實現方法

          方法一:繼承Thread類,覆蓋方法run(), public class MyThread extends Thread { int count= 1, number; public MyThread(int num) { number = num;

執行種實現方法?同步有種實現方法?

為何要使用同步? java允許多執行緒併發控制,當多個執行緒同時操作一個可共享的資源變數時(如資料的增刪改查),  將會導致資料不準確,相互之間產生衝突,因此加入同步鎖以避免在該執行緒沒有完成操作之前,被其他執行緒的呼叫,  從而保證了該變數的唯一性和準確性。 同步的

Java 執行 學習筆記(二)停止執行方法

1.異常法: package test; import exthread.MyThread; import exthread.MyThread; public class Run { pu

java執行之使用interrupt停止執行方法

停止執行緒 停止執行緒是java多執行緒開發中很重要的技術點,實際工作中很多業務都有類似的需求,掌握此技術可以對業務中所需停止的執行緒做有效的處理。但是停止執行緒在java語言中並不像break語句中那樣乾脆簡單,還需要我們做一下技巧性的處理。 如何更好的停

執行——常用操作方法(二)

多執行緒常用操作可以總結成一下七種。 1、取得當前執行緒物件: public static native Thread currentThread();  2、執行緒的命名和取得當前執行緒的名字:public Thread(Runnable terget,String n

執行常用方法統計

currentThread(): currentThread()方法可返回程式碼段正在被那個執行緒呼叫的資訊。 isAlive(): 方法isAlive()的功能是判斷當前的執行緒是否處於活動狀態。 sleep(): 在指定的毫秒數內讓當前“正在執行的執行緒”休眠(暫停執

Java 執行常用操作方法

1.多執行緒常用方法:    currentThread() :  獲取當前執行的執行緒    getName() : 獲取執行緒名稱    setName() : 設定執行緒名稱    sleep(long millis) :  是一個靜態方法,使當前執行執行緒進入睡眠狀態

Java 執行 join和interrupt 方法

簡述: 使用Java多執行緒中join和interrupt函式 《Java程式設計思想》 P669 ~ P670 一個執行緒可以再其他執行緒上呼叫join()方法,其效果是等待一段時間直到第二個執行緒結束才繼續執行。 如果某個執行緒在另一個執行緒t上呼叫t.join(), 此

建立執行的兩種方法

建立執行緒的方法: 一種方法是將類宣告為 Thread 的子類。該子類應重寫 Thread 類的 run 方法。接下來可以分配並啟動該子類的例項。 public class MyThread extends Thread{

java 執行synchronized鎖同步方法,同步程式碼塊

執行緒安全問題 同步和非同步 我們知道多個執行緒共享堆記憶體,當兩個或者多個執行緒呼叫同一個物件的方法操作物件成員時,因為cpu輪流執行執行緒,執行緒A剛開始操作物件方法,修改了資料,輪到執行緒B執行,執行緒B也操作物件方法,修改資料,可能又輪到執行緒A操作物件方法,接著上次執行緒A的剩餘部

執行的三特性理解執行開發

       工作中許多地方需要涉及到多執行緒的設計與開發,java多執行緒開發當中我們為了執行緒安全所做的任何操作其實都是圍繞多執行緒的三個特性:原子性、可見性、有序性展開的。針對這三個特性的資料網上已經很多了,在這裡我希望在站在便於理解的角度,用相對直觀的方式闡述這

執行常用面試題

一 面試中關於 synchronized 關鍵字的 5 連擊 1.1 說一說自己對於 synchronized 關鍵字的瞭解  synchronized關鍵字解決的是多個執行緒之間訪問資源的同步性,synchronized關鍵字可以保證被它修飾的方法或者程式碼塊在任意時刻只能有