1. 程式人生 > >Java中Synchronized修飾不同位置的用法

Java中Synchronized修飾不同位置的用法

/**
 * demo1: synchronized的用法
 * 一個執行緒訪問一個物件中的synchronized(this)同步程式碼塊時,其他試圖訪問該物件的執行緒將被阻塞
 */
public class SyncThread extends Thread {

    private static int count;

    public SyncThread() {
        count = 0;
    }

    public  void run() {
        synchronized(this) {
            for (int i = 0; i < 5; i++) {
                try {
                    System.out.println(Thread.currentThread().getName() + ":" + (count++));
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public int getCount() {
        return count;
    }

    public static void main(String[] args) {

        // 只有一把鎖
        SyncThread syncThread = new SyncThread();
        Thread thread1 = new Thread(syncThread, "SyncThread1");
        Thread thread2 = new Thread(syncThread, "SyncThread2");
        thread1.start();
        thread2.start();

        // 會有兩把鎖, syncThread1 對應一把鎖, syncThread2 對應一把鎖
//        SyncThread syncThread1 = new SyncThread();
//        SyncThread syncThread2 = new SyncThread();
//        Thread thread1 = new Thread(syncThread1, "SyncThread1");
//        Thread thread2 = new Thread(syncThread2, "SyncThread2");
//        thread1.start();
//        thread2.start();
    }
}

/**
 * demo2 多個執行緒訪問synchronized和非synchronized程式碼塊
 * 程式碼中countAdd是一個synchronized的,printCount是非synchronized的。
 * 從結果中可以看出一個執行緒訪問一個物件的synchronized程式碼塊時,
 * 別的執行緒可以訪問該物件的非synchronized程式碼塊而不受阻塞。
 */
public class Counter implements Runnable {

    private int count;

    public Counter() {
        count = 0;
    }

    public void countAdd() {
        synchronized(this) {
            for (int i = 0; i < 5; i ++) {
                try {
                    System.out.println(Thread.currentThread().getName() + ":" + (count++));
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //非synchronized程式碼塊,未對count進行讀寫操作,所以可以不用synchronized
    public void printCount() {
        for (int i = 0; i < 5; i ++) {
            try {
                System.out.println(Thread.currentThread().getName() + " count:" + count);
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void run() {
        String threadName = Thread.currentThread().getName();
        if (threadName.equals("A")) {
            countAdd();
        } else if (threadName.equals("B")) {
            printCount();
        }
    }

    public static void main(String[] args) {
        Counter counter = new Counter();
        Thread thread1 = new Thread(counter, "A");
        Thread thread2 = new Thread(counter, "B");
        thread1.start();
        thread2.start();
    }
}
/**
 * demo3 :指定要給某個物件加鎖
 * 在AccountOperator 類中的run方法裡,我們用synchronized 給account物件加了鎖。
 * 這時,當一個執行緒訪問account物件時,其他試圖訪問account物件的執行緒將會阻塞,
 * 直到該執行緒訪問account物件結束。也就是說誰拿到那個鎖誰就可以執行它所控制的那段程式碼。
 */
public class Demo3 {

    /**
     * 銀行賬戶類
     */
    class Account {
        String name;
        float amount;

        public Account(String name, float amount) {
            this.name = name;
            this.amount = amount;
        }
        //存錢
        public  void deposit(float amt) {
            amount += amt;
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //取錢
        public  void withdraw(float amt) {
            amount -= amt;
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        public float getBalance() {
            return amount;
        }
    }

    /**
     * 賬戶操作類
     */
    class AccountOperator implements Runnable{
        private Account account;

        private byte[] bytes = new byte[0];

        public AccountOperator(Account account) {
            this.account = account;
        }

        @Override
        public void run() {
            synchronized (account) {
                account.deposit(500);
                account.withdraw(500);
                System.out.println(Thread.currentThread().getName() + ":" + account.getBalance());
            }
//            account.deposit(500);
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            account.withdraw(500);
//            System.out.println(Thread.currentThread().getName() + ":" + account.getBalance());
        }
    }

    public void test() {
        Account account = new Account("zhang san", 10000.0f);
        AccountOperator accountOperator = new AccountOperator(account);

        final int num = 5;
        Thread threads[] = new Thread[num];
        for (int i = 0; i < num; i ++) {
            threads[i] = new Thread(accountOperator, "Thread" + i);
            threads[i].start();
        }
    }

    public static void main(String[] args) {
      Demo3 d = new Demo3();
      d.test();
    }

}
2:修飾一個方法

相關推薦

JavaSynchronized修飾不同位置用法

/** * demo1: synchronized的用法 * 一個執行緒訪問一個物件中的synchronized(this)同步程式碼塊時,其他試圖訪問該物件的執行緒將被阻塞 */ public class SyncThread extends Thread { private static

javasynchronized修飾程式碼塊(兩種建立執行緒的方式講解賣票程式)

格式: synchronized(類物件名 aa) { //同步程式碼塊 } 功能: synchronized(類物件名 aa)的含義是:判斷aa是否已經被其他執行緒所霸佔,如果發現已經被其他執行緒霸

JavaSynchronized用法

turn 效果 互斥 obj href sta dem data 總結 《編程思想之多線程與多進程(1)——以操作系統的角度述說線程與進程》一文詳細講述了線程、進程的關系及在操作系統中的表現,這是多線程學習必須了解的基礎。本文將接著講一下Java線程同步中的一個

Java開發synchronized的定義及用法

synchronized是java中用於同步的關鍵字,其典型的作用域如下所示. 1 物件鎖 @Slf4jpublic class SynchronizedExample1 { private final int loopNum = 20; // 修飾一個程式碼塊 private

Javafinal修飾符對不同變數的不同影響

final修飾符可以用來修飾類、方法和變數,用於表示它修飾的類、方法和變數不可改變。final修飾變數時,表示該變數一旦獲得了初始值就不可被改變。 由於final變數獲取初始值之後就不能重新賦值,所以final修飾成員變數和區域性變數時有一定程度的不同。 final

javasynchronized用法

} class TxtThread implements Runnable {  int num = 100;  String str = new String();  public void run()  {   while (true)   {    synchronized(str)    {    i

Javasynchronized 和 ReentrantLock 有什麼不同

        Java在過去很長一段時間只能通過synchronized關鍵字來實現互斥,它有一些缺點。比如你不能擴充套件鎖之外的方法或者塊邊界,嘗試獲取鎖時不能中途取消等。Java 5 通過Lock

javasynchronized用法詳解

synchronized Java語言的關鍵字,當它用來修飾一個方法或者一個程式碼塊的時候,能夠保證在同一時刻最多隻有一個執行緒執行該段程式碼。 第一篇:      一、當兩個併發執行緒訪問同一個物件object中的這個synchronized(this)同步程式碼

JavaPreparedStatement和Statement的用法區別

aik txt 實例 什麽 一點 所有 一個 drop passwd Java中PreparedStatement和Statement的用法區別 (2012-08-01 11:06:44) 轉載▼ 標簽: 雜談 1、 PreparedStatem

javaVolatile修飾符的含義

線程 代碼 sync 一個 vol tracking ava 變量 拷貝 在java語言中:為了獲得最佳速度,同意線程保存共享成員變量的私有拷貝。並且僅僅當線程進入或者離開同步代碼塊時才與共享成員變量的原始值進行對照。

java訪問修飾

addclass ext pri post span 沒有 pretty pub () 較之c++ 中 public,proctected, private 三種訪問控制, java多了默認訪問控制。 java中四種訪問控制權限 簡單描寫敘述為一下四

Javasynchronized關鍵字理解

監視器 pre 定義 exc 執行 zed 三種 gen 好記性不如爛筆頭 好記性不如爛筆頭~~ 並發編程中synchronized關鍵字的地位很重要,很多人都稱它為重量級鎖。利用synchronized實現同步的基礎:Java中每一個對象都可以作為鎖。具體表現為以下三種形

Javathis和super的用法總結

return 類繼承 xtend chinese ati -s sha blog 定義 在JAVA類中使用super來引用父類的成分,用this來引用當前對象。 如果一個類從另外一個類繼承,我們new這個子類的實例對象的時候,這個子類對象裏面會有一個父類對象。怎麽去引用裏面

Java各運算符的用法

一律 邏輯與 算術運算 功能 字符串 變量 “.” 條件 若是 Java的運算符可分為4類:算術運算符、關系運算符、邏輯運算符和位運算符。1.算術運算符 Java的算術運算符分為一元運算符和二元運算符。一元運算符只有一個操作數;二元運算符有兩個操作數,運算符位於兩個

JavaBigDecimal類介紹及用法

exceptio decimal body ue4 mage oat 比較運算符 mod 乘法   Java中提供了大數字(超過16位有效位)的操作類,即 java.math.BinInteger 類和 java.math.BigDecimal 類,用於高精度計算.   其

Java修飾符及其作用

java修飾符修飾符類型修飾符說明訪問控制修飾符defaultdefault (即缺省,什麽也不寫): 在同一包內可見,不使用任何修飾符。使用對象:類、接口、變量、方法。privateprivate : 在同一類內可見。使用對象:變量、方法。 註意:不能修飾類(外部類)publicpublic : 對所有

JAVAthis的三種用法的詳解

enc 所有 其它 println 用途 詳細介紹 示例 一次 調用構造   this關鍵字必須放在非靜態方法裏面 this關鍵字代表自身,在程序中主要的使用用途有以下幾個方面:    使用this關鍵字引用成員變量    使用this關鍵字在自身構造方法內部引用其它構造方

解析Javafinal關鍵字的各種用法

col 後序 blog str 訪問 人類 依然 fin 可能 首先,我們可以從字面上理解一下final這個英文單詞的中文含義:“最後的,最終的; 決定性的; 不可更改的;”。顯然,final關鍵詞如果用中文來解釋,“不可更改的”更為合適。當你在編寫程序,可能

Java分割字串split()的用法小結

用"."做分隔符,必須是如下寫法 String.split("\\."),不能是String.split("."); 用"|"做分隔符,必須是如下的寫法 String.split("\\|"),不能是String.split("|"); 如果在一個字串中有多

javaSynchronized的方法介紹

Java中Synchronized的用法 synchronized是Java中的關鍵字,是一種同步鎖。它修飾的物件有以下幾種: 1. 修飾一個程式碼塊,被修飾的程式碼塊稱為同步語句塊,其作用的範圍是大括號{}括起來的程式碼,作用的物件是呼叫這個程式碼塊的物件; 2. 修飾一個方法,被修