Java學習27 2020-03-13

內容

1.線程中的兩個不常用方法介紹
2.線程同步機制初步

一.線程中的兩個不常用方法介紹

1.Thread.yield()

Thread.yield()與sleep()類似,只是不能由用戶指定暫停多長時間,并且yield()方法只能讓同優先級的線程有執行的機會,讓位時間不固定
注意:該方法也是一個靜態方法

2.t.join()

t.join()是線程合并,合并之后就可能變成了單線程的程序。
這一行代碼出現在哪個線程中,t就和哪個線程合并。從這也可以看出,join()是成員方法

二.線程同步機制初步

1.先了解兩個概念

①異步編程模型:t1線程執行t1的,t2線程執行t2的,兩個線程之間誰也不等誰(一般情況下效率更高)
②同步編程模型:t1線程和t2線程執行,但t1線程必須等t2線程執行結束之后,t1線程才能執行,這就是同步編程模型(也就是接下來要講的)

2.為何要引入線程同步?

為了數據的安全。盡管應用程序的使用效率降低了。
線程同步機制使程序變成了(等同)單線程。

3.什么條件下使用線程同步?

①必須是多線程環境
②多線程環境共享同一個數據
③共享的數據涉及修改操作(比如只涉及查找操作,那就不需要線程同步)

4.錯誤示范

以下程序不使用線程同步機制,多線程同時對同一個賬戶進行取款操作,看看會出現什么問題


public class 測試程序   {                                                                                                             
                                                                                                                        
    public static void main(String[] args) throws InterruptedException  {
   
        //創建一個公共的賬戶
        Account act = new Account("actno",5000.0);
        
        //創建兩個線程,這兩個線程對同一個賬戶取款
        Thread t1 = new Thread(new Processor(act));
        Thread t2 = new Thread(new Processor(act));
   
        //開始取款
        t1.start();
        t2.start();
                
    }

   
    
}

//取款線程
class Processor implements Runnable{
    
    //賬戶
    Account act;
    
    //構造方法
    Processor(Account act){
        this.act = act;
    }
    
    public void run() {
        act.withdraw(1000);
        System.out.println("取款1000元成功,余額為:" + act.getBalance());
    }
}
//賬戶
class Account{
    
    private String actno;
    private double balance;
    
    //構造方法
    public Account(String actno,double balance) {
        this.actno = actno;
        this.balance = balance;
    }
    
    //setter and getter
    public void setBalance(double balance) {
        this.balance = balance;
    }
    
    public double getBalance() {
        return balance;
    }
    
    //對外提供一個取款的方法
    public void withdraw(double money) {
        double after = balance - money;
        
        //更新余額
        this.setBalance(after);
    }
}


輸出結果

取款1000元成功,余額為:4000.0
取款1000元成功,余額為:4000.0

這就已經不對了,取出來2000.0,應該還剩3000.0
所以我們對于類似這種情況,就要使用線程同步了

5.線程同步的語法

synchronized(共享對象){}
{}里面放需要同步的代碼

6.以下程序使用線程同步機制

public class 測試程序   {                                                                                                             
                                                                                                                        
    public static void main(String[] args) throws InterruptedException  {
   
        //創建一個公共的賬戶
        Account act = new Account("actno",5000.0);
        
        //創建兩個線程,這兩個線程對同一個賬戶取款
        Thread t1 = new Thread(new Processor(act));
        Thread t2 = new Thread(new Processor(act));
   
        //開始取款
        t1.start();
        t2.start();
                
    }

   
    
}

//取款線程
class Processor implements Runnable{
    
    //賬戶
    Account act;
    
    //構造方法
    Processor(Account act){
        this.act = act;
    }
    
    public void run() {
        act.withdraw(1000);
        System.out.println("取款1000元成功,余額為:" + act.getBalance());
    }
}
//賬戶
class Account{
    
    private String actno;
    private double balance;
    
    //構造方法
    public Account(String actno,double balance) {
        this.actno = actno;
        this.balance = balance;
    }
    
    //setter and getter
    public void setBalance(double balance) {
        this.balance = balance;
    }
    
    public double getBalance() {
        return balance;
    }
    
    //對外提供一個取款的方法
    public void withdraw(double money) {
        
        synchronized(this) {
            double after = balance - money;
            
            //延遲
            try{Thread.sleep(1000);}catch(Exception e) {}
            
            //更新余額
            this.setBalance(after); 
        }
        
    }
}


輸出結果

取款1000元成功,余額為:4000.0
取款1000元成功,余額為:3000.0

而且是每1s輸出一行
這樣就是我們需要的,雖然效率降低了,但是安全是最重要的

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Java多線程學習 [-] 一擴展javalangThread類 二實現javalangRunnable接口 三T...
    影馳閱讀 2,986評論 1 18
  • 本文主要講了java中多線程的使用方法、線程同步、線程數據傳遞、線程狀態及相應的一些線程函數用法、概述等。 首先講...
    李欣陽閱讀 2,492評論 1 15
  • 進程:正在執行的程序,是一個動態的過程 線程:是進程中用于控制程序執行的控制單元(執行路徑,執行情景) 進程中至少...
    寶塔山上的貓閱讀 451評論 0 1
  • 1. 線程和進程的區別? 它們是不同的操作系統資源管理方式。進程有獨立的地址空間,一個進程崩潰后,在保護模式下不會...
    Darkmoss閱讀 537評論 0 0
  • 一擴展javalangThread類二實現javalangRunnable接口三Thread和Runnable的區...
    和帥_db6a閱讀 497評論 0 1