Java線程同步執行個體分析_java

來源:互聯網
上載者:User

本文執行個體講述了Java線程同步的用法。分享給大家供大家參考。具體分析如下:

多線程的使用為我們的程式提供了眾多的方便,同時它也給我們帶來了以往沒有考慮過的麻煩。當我們使用多執行緒共用資源時意外將會發生:比如我們一起外出就餐,每個人都是一個線程,餐桌上的食物則是共用資源,當我看到紅燒雞腿上桌後立即拿起筷子直奔目標,眼看著就得手的時候,突然~~~雞腿消失了,一個距離盤子更近的線程正在得意地啃著。

為了避免上述問題的發生,Java為我們提供了“synchronized(同步化)修飾符”來避免資源衝突,你可以將資源類中某個函數或變數聲明為synchronized(同步化),每個繼承自Object的類都含有一個機鎖(Lock),它是餘生俱來的,不需要編寫任何代碼來啟用它。當我們調用任何synchronized(同步化)函數時,該對象將被鎖定,對象中所有 synchronized(同步化)函數便無法被調用,直到第一個函數執行完畢並解除機鎖。

import java.awt.BorderLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTextArea;import javax.swing.JTextField;/** * 線程同步 * 我們類比一個銀行預存程序來證明線程同步的必要性以及在Java中進行線程同步的方法 * 重點:synchronized 修飾符 */public class TestMain5 extends JFrame { private MyAccounts myAccounts = null; // 我的帳號 private JTextField text = null; // 銀行存款數額顯示 private JTextArea textArea = null; // 交易過程顯示 private JButton button = null; // 開始類比交易的按鈕 /**  * 構造一個銀行存取款介面  */ public TestMain5(){  super("線程同步測試");  myAccounts = new MyAccounts();  text = new JTextField(Integer.toString(myAccounts.inquire()), 10); // 我們在銀行中的初始存款為100  textArea = new JTextArea();  textArea.setText("交易日誌:");  JScrollPane sp = new JScrollPane(textArea);  button = new JButton("開始交易");  button.addActionListener(new ActionListener(){   public void actionPerformed(ActionEvent e) {    new Bank("鐘樓支行", myAccounts, Bank.DEAL_SAVING, 800);    new Bank("高新支行", myAccounts, Bank.DEAL_SAVING, 1300);    new Bank("小寨支行", myAccounts, Bank.DEAL_FETCH, 200);    new Bank("雁塔支行", myAccounts, Bank.DEAL_FETCH, 400);    new Bank("興慶支行", myAccounts, Bank.DEAL_SAVING, 100);    new Bank("土門支行", myAccounts, Bank.DEAL_FETCH, 700);   }  });  JPanel pane = new JPanel();  pane.add(text);  pane.add(button);  this.getContentPane().add(pane, BorderLayout.NORTH);  this.getContentPane().add(sp);  this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  this.setSize(300, 200);  this.setLocationRelativeTo(null);  this.setVisible(true); } /**  * 銀行交易大廳類  * 一般銀行都會有N個交易大廳,這些大廳可以同時處理多筆業務,這正好符合多線程的特點  */ class Bank extends Thread{  /**   * 靜態欄位:用於表示儲存   */  public static final int DEAL_SAVING = 0;  /**   * 靜態欄位:用於表示提取   */  public static final int DEAL_FETCH = 1;  private int buy = Bank.DEAL_FETCH; // 預設使取款  private int count = 0;  private MyAccounts myAccounts = null; // 我的帳號  /**   * 構造這個銀行交易大廳   * @param name 這個交易大廳的名稱   * @param myAccounts 我的銀行帳號   * @param buy 行為,參考欄位:DEAL_SAVING或DEAL_FETCH   * @param count 錢的數量   */  public Bank(String name, MyAccounts myAccounts, int buy, int count){   super(name);   this.myAccounts = myAccounts;   this.buy = buy;   this.count = count;   this.start();  }  public void run(){   int $count = 0;   if(buy == Bank.DEAL_SAVING){ // 如果是存款業務    $count = myAccounts.saving(count);   }else if(buy == Bank.DEAL_FETCH){ // 如果是取款業務    $count = myAccounts.fetch(count);   }   text.setText(Integer.toString($count));   textArea.append("\n" + this.getName() + " " + (buy == Bank.DEAL_SAVING ? "存款": "取款") + " 金額:" + count + " 結餘:" + $count);  } } /**  * 我的帳號  * 進行同步測試  */ class MyAccounts{  private Integer count = 1100;  public MyAccounts(){  }  /**   * 查詢我的帳號   */  public int inquire(){   synchronized (count){    return count;   }  }  /**   * 存款業務   * @param c 存款的數量   * @return 業務辦理完成後的數量   */  public int saving(int c){   synchronized (count){    //return count += c; // 為了能更好的觀察,我們將這個簡潔的語句注釋掉    int $count = inquire(); // 先查詢帳戶中的存款    $count += c;    try {     Thread.sleep(1000); // 為了更好的觀察,使業務在此停頓1秒鐘    } catch (InterruptedException ex) {     ex.printStackTrace();    }    count = $count; // 最後將總數儲存起來    return inquire(); // 返回最新的存款數   }  }  /**   * 取款業務   * @param c 取款的數量   * @return 業務辦理完成後的數量   */  public int fetch(int c){   synchronized (count){    //return count -= c; // 為了能更好的觀察,我們將這個簡潔的語句注釋掉    int $count = inquire(); // 先查詢帳戶中的存款    $count -= c;    try {     Thread.sleep(1000); // 為了更好的觀察,使業務在此停頓1秒鐘    } catch (InterruptedException ex) {     ex.printStackTrace();    }    count = $count; // 最後將總數儲存起來    return inquire(); // 返回最新的存款數   }  } } public static void main(String [] args){  new TestMain5(); }}

希望本文所述對大家的java程式設計有所協助。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.