程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java線程:線程的同步-同步塊

Java線程:線程的同步-同步塊

編輯:關於JAVA

追其同步的根本的目的,是控制競爭資源的正確的訪問,因此只要在訪問競爭資源的時候保證同一時刻只能一個線程訪問即可,因此Java引入了同步代碼快的策略,以提高性能。

在上個例子的基礎上,對oper方法做了改動,由同步方法改為同步代碼塊模式,程序的執行邏輯並沒有問題。

/**
* Java線程:線程的同步-同步代碼塊
*
* @author leizhimin 
*/
public class Test {
         public static void main(String[] args) {
                 User u = new User("張三", 100);
                 MyThread t1 = new MyThread("線程A", u, 20);
                 MyThread t2 = new MyThread("線程B", u, -60);
                 MyThread t3 = new MyThread("線程C", u, -80);
                 MyThread t4 = new MyThread("線程D", u, -30);
                 MyThread t5 = new MyThread("線程E", u, 32);
                 MyThread t6 = new MyThread("線程F", u, 21);
                 t1.start();
                 t2.start();
                 t3.start();
                 t4.start();
                 t5.start();
                 t6.start();
         }
}
class MyThread extends Thread {
         private User u;
         private int y = 0;
         MyThread(String name, User u, int y) {
                 super(name);
                 this.u = u;
                 this.y = y;
         }
         public void run() {
                 u.oper(y);
         }
}
class User {
         private String code;
         private int cash;
         User(String code, int cash) {
                 this.code = code;
                 this.cash = cash;
         }
         public String getCode() {
                 return code;
         }
         public void setCode(String code) {
                 this.code = code;
         }
         /**
          * 業務方法 
          *
          * @param x 添加x萬元
          */
         public void oper(int x) {
                 try {
                         Thread.sleep(10L);
                         synchronized (this) {
                                 this.cash += x;
                                 System.out.println(Thread.currentThread().getName() + "運行結束,增加“" + x + "”,當前用戶賬戶余額為:" + cash);
                         }
                         Thread.sleep(10L);
                 } catch (InterruptedException e) {
                         e.printStackTrace();
                 }
         }
         @Override 
         public String toString() {
                 return "User{" +
                                 "code='" + code + '\'' +
                                 ", cash=" + cash +
                                 '}';
         }
}

線程E運行結束,增加“32”,當前用戶賬戶余額為:132
線程B運行結束,增加“-60”,當前用戶賬戶余額為:72
線程D運行結束,增加“-30”,當前用戶賬戶余額為:42
線程F運行結束,增加“21”,當前用戶賬戶余額為:63
線程C運行結束,增加“-80”,當前用戶賬戶余額為:-17
線程A運行結束,增加“20”,當前用戶賬戶余額為:3
Process finished with exit code 0

注意:

在使用synchronized關鍵字時候,應該盡可能避免在synchronized方法或synchronized塊中使用sleep或者 yield方法,因為synchronized程序塊占有著對象鎖,你休息那麼其他的線程只能一邊等著你醒來執行完了才能執行。不但嚴重影響效率,也不合邏輯。

同樣,在同步程序塊內調用yeild方法讓出CPU資源也沒有意義,因為你占用著鎖,其他互斥線程還是無法訪問同步程序塊。當然與同步程序塊無關的線程可以獲得更多的執行時間。

出處:http://lavasoft.blog.51cto.com/62575/221922

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved