1. 程式人生 > >同步方法和同步程式碼塊的區別

同步方法和同步程式碼塊的區別


為何要使用同步?  java允許多執行緒併發控制,當多個執行緒同時操作一個可共享的資源變數時(如資料的增刪改查),      將會導致資料不準確,相互之間產生衝突,因此加入同步鎖以避免在該執行緒沒有完成操作之前,被其他執行緒的呼叫,      從而保證了該變數的唯一性和準確性。 1.同步方法  即有synchronized關鍵字修飾的方法。      由於java的每個物件都有一個內建鎖,當用此關鍵字修飾方法時,      內建鎖會保護整個方法。在呼叫該方法前,需要獲得內建鎖,否則就處於阻塞狀態。 程式碼如:      public synchronized void save(){}    注: synchronized關鍵字也可以修飾靜態方法,此時如果呼叫該靜態方法,將會鎖住整個類 2.同步程式碼塊  即有synchronized關鍵字修飾的語句塊。      被該關鍵字修飾的語句塊會自動被加上內建鎖,從而實現同步     程式碼如:      synchronized(object){      }     注:同步是一種高開銷的操作,因此應該儘量減少同步的內容。      通常沒有必要同步整個方法,使用synchronized程式碼塊同步關鍵程式碼即可。   程式碼例項: 
/**      * 執行緒同步的運用      *       * @author XIEHEJUN      *       */     public class SynchronizedThread {         class Bank {             private int account = 100;             public int getAccount() {                 return account;             }             /**              * 用同步方法實現              *               * @param money              */             public synchronized void save(int money) {                 account += money;             }             /**              * 用同步程式碼塊實現              *               * @param money              */             public void save1(int money) {                 synchronized (this) {                     account += money;                 }             }         }         class NewThread implements Runnable {             private Bank bank;             public NewThread(Bank bank) {                 this.bank = bank;             }             @Override             public void run() {                 for (int i = 0; i < 10; i++) {                     // bank.save1(10);                     bank.save(10);                     System.out.println(i + "賬戶餘額為:" + bank.getAccount());                 }             }         }         /**          * 建立執行緒,呼叫內部類          */         public void useThread() {             Bank bank = new Bank();             NewThread new_thread = new NewThread(bank);             System.out.println("執行緒1");             Thread thread1 = new Thread(new_thread);             thread1.start();             System.out.println("執行緒2");             Thread thread2 = new Thread(new_thread);             thread2.start();         }         public static void main(String[] args) {             SynchronizedThread st = new SynchronizedThread();             st.useThread();         }     } 3.使用重入鎖實現執行緒同步 在
Java
SE5.0中新增了一個java.util.concurrent包來支援同步。      ReentrantLock類是可重入、互斥、實現了Lock介面的鎖,      它與使用synchronized方法和快具有相同的基本行為和語義,並且擴充套件了其能力     ReenreantLock類的常用方法有:         ReentrantLock() : 建立一個ReentrantLock例項          lock() : 獲得鎖          unlock() : 釋放鎖      注:ReentrantLock()還有一個可以建立公平鎖的構造方法,但由於能大幅度降低程式執行效率,不推薦使用      例如:          在上面例子的基礎上,改寫後的程式碼為:      程式碼例項:  //只給出要修改的程式碼,其餘程式碼與上同         class Bank {             private int account = 100;             //需要宣告這個鎖             private Lock lock = new ReentrantLock();             public int getAccount() {                 return account;             }             //這裡不再需要synchronized              public void save(int money) {                 lock.lock();                 try{                     account += money;                 }finally{                     lock.unlock();                 }             }         }     注:關於Lock物件和synchronized關鍵字的選擇:          a.最好兩個都不用,使用一種java.util.concurrent包提供的機制,              能夠幫助使用者處理所有與鎖相關的程式碼。          b.如果synchronized關鍵字能滿足使用者的需求,就用synchronized,因為它能簡化程式碼          c.如果需要更高階的功能,就用ReentrantLock類,此時要注意及時釋放鎖,否則會出現死鎖,通常在finally程式碼釋放鎖  4.使用區域性變數實現執行緒同步  如果使用ThreadLocal管理變數,則每一個使用該變數的執行緒都獲得該變數的副本,      副本之間相互獨立,這樣每一個執行緒都可以隨意修改自己的變數副本,而不會對其他執行緒產生影響。     ThreadLocal 類的常用方法     ThreadLocal() : 建立一個執行緒本地變數      get() : 返回此執行緒區域性變數的當前執行緒副本中的值      initialValue() : 返回此執行緒區域性變數的當前執行緒的"初始值"      set(T value) : 將此執行緒區域性變數的當前執行緒副本中的值設定為value     例如:          在上面例子基礎上,修改後的程式碼為:      程式碼例項:  //只改Bank類,其餘程式碼與上同         public class Bank{             //使用ThreadLocal類管理共享變數account             private static ThreadLocal<Integer> account = new ThreadLocal<Integer>(){                 @Override                 protected Integer initialValue(){                     return 100;                 }             };             public void save(int money){                 account.set(account.get()+money);             }             public int getAccount(){                 return account.get();             }         }     注:ThreadLocal與同步機制          a.ThreadLocal與同步機制都是為了解決多執行緒中相同變數的訪問衝突問題。          b.前者採用以"空間換時間"的方法,後者採用以"時間換空間"的方式 

相關推薦

synchronized的修飾方法修飾程式碼區別

文章思路 哪些概念難理解 類鎖和物件鎖區別 類鎖所有物件一把鎖 物件鎖一個物件一把鎖,多個物件多把鎖 同步是對同一把鎖而言的,同步這個概念是在多個執行緒爭奪同一把鎖的時候才能實現的,如果多個執行緒爭奪不同的鎖,那多個執行緒是不能同步的 兩個執行緒一

深入理解使用synchronized同步方法同步程式碼區別

一.程式碼塊和方法之間的區別 首先需要知道程式碼塊和方法有什麼區別: 構造器和方法塊,構造器可以過載也就是說明在建立物件時可以按照不同的構造器來建立,那麼構造器是屬於物件,而程式碼塊呢他是給所有的物件初始化的。底下看一個列子: public class Constructor_Methodbloc

同步方法同步程式碼區別

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

java的同步方法同步程式碼,物件鎖,類鎖區別

/** * @author admin * @date 2018/1/12 10:33 * 作用在同一個例項物件上討論 * Synchronized同步方法和同步程式碼塊 * 1、synchronized和synchronized(this)二者沒區別,都作用在this物件鎖上面,所以會同步 *

同步方法同步程式碼的使用區別

同步方法的使用:在方法上加synchronized public synchronized void execute() { for(int i = 0; i < 20; i++) { try { Thread.sleep(

多執行緒併發問題以及單例設計模式與執行緒安全以及同步方法同步程式碼

執行緒安全和非執行緒安全 在作業系統中,執行緒是不擁有資源的,程序擁有資源。執行緒是由程序建立的,一個程序可以建立多個執行緒,這些執行緒共享程序中的資源。當多個執行緒同時操作一個變數時,這個時候就可能會造成資料的不一致性,此時就是執行緒不安全。 JVM有主記

同步方法同步程式碼的區別是什麼

在Java語言中,每一個物件有一把鎖。執行緒可以使用synchronized關鍵字來獲取物件上的鎖。synchronized關鍵字可應用在方法級別(粗粒度鎖)或者是程式碼塊級別(細粒度鎖)。 問題的由來: 看到這樣一個面試題: //下列兩個方法有什麼區別 public synchronized voi

執行緒中的同步程式碼synchronized、同步方法同步鎖Lock

在學習執行緒的時候,因為執行緒的排程具有不確定性,所以銀行取錢問題、多個視窗售賣火車票問題都是反應多執行緒的優越性以及不確定性。當程式中有多個併發執行緒在進入一個程式碼塊中並且修改其中引數時,就很有可能引發執行緒安全問題從而造成異常。 同步程式碼塊 所以,j

JAVA基礎(50)---靜態方法靜態程式碼

靜態方法                       用static修飾的方法。靜

多執行緒(2)-synchronized方法synchronized程式碼的用法

  前言        在介紹synchronized方法和synchronized程式碼塊前,先對監視器(Monitor)做一個說明,在java虛擬機器中,每個物件(object和class)通過某種邏輯關聯監視器,每個監視器和一個物件引用

深入理解使用synchronized同步方法同步代碼區別

sys http ted 兩個 方法 ext tar extends idt 一.代碼塊和方法之間的區別 首先需要知道代碼塊和方法有什麽區別: 構造器和方法塊,構造器可以重載也就是說明在創建對象時可以按照不同的構造器來創建,那麽構造器是屬於對象,而代碼塊呢他是給所有的對象初

Java基礎知識之synchronized同步方法程式碼、靜態方法、靜態程式碼區別

      Java中的同步塊用synchronized標記,是同步在某個物件上,所有同步在一個物件上的同步塊在同一時刻只能被一個執行緒進入並執行操作,其他等待進入該同步塊的執行緒將被阻塞,直到執行該同步塊中的執行緒退出。 有四種不同的同步塊: 例項方法同步;

同步方法同步程式碼區別

synchronized 方法控制類成員的訪問:每個類實力對應一把鎖,每個synchronized方法都必須獲得呼叫改方法的例項的所才能執行,否則所屬執行緒阻塞,方法一旦執行,就獨佔該鎖,直到從該方法返回時才將鎖釋放,此後被阻塞的執行緒方能獲得該鎖,重新進入可執行狀態。這種

執行緒-synchronized方法同步的作用範圍;synchronized(this)synchronized(obj)的區別

原文:http://m.blog.csdn.net/blog/u010802573/38661719 參考資源: http://www.cnblogs.com/oracleDBA/archive/2010/05/22/1741642.html http://www

同步方法同步代碼的區別是什麽?

關鍵字 ont 當前 默認 style 而不是 span ron 加鎖 同步方法默認用this或者當前類class對象作為鎖。 同步代碼可以選擇以什麽來加鎖,比同步方法更細顆粒化,同步代碼可以同步有同步問題的部分代碼而不是整個方法。 同步方法用關鍵字synchronized

synchronized對普通同步方法對靜態方法區別

synchronized是一個重量級鎖,我們都知道該關鍵字鎖住的是物件而不是程式碼本身,那麼對於靜態方法和同步方法有什麼不同呢,通過如下程式碼進行測試 public class SynchronizedTest { private static int num; pri

java synchronized同步靜態方法同步非靜態方法區別與舉例

synchronized關鍵字是java併發程式設計中為了解決執行緒對共享資源的競爭造成錯誤,而提供的解決方案。synchronized關鍵字有兩種用法,一種是隻用於方法的定義中,另外一種是synchronized塊,我們不僅可以使用synchronized來同步一個物件

Java: synchronized詳解,靜態同步方法,普通同步方法同步程式碼

對程式碼進行同步控制我們可以選擇同步方法,也可以選擇同步塊,這兩種方式各有優缺點,至於具體選擇什麼方式,就見仁見智了,同步塊不僅可以更加精確的控制物件鎖,也就是控制鎖的作用域,何謂鎖的作用域?鎖的作用域就是從鎖被獲取到其被釋放的時間。而且可以選擇要獲取哪個物

同步方法同步區別

java使用synchronized同步,分為四種情況:   例項方法同步   例項方法中同步塊   靜態方法同步   靜態方法中同步塊 我們從兩個方面來說他們的不同,一個是同步方法和同步塊的區別,一個是靜態和非靜態的區別。 同步方法就是在方法前加關鍵字synch

java中構造程式碼、static程式碼區域性程式碼區別

先上程式碼: class StaticCode{ int age; // static程式碼塊 static{ System.out.println("static程式碼塊"); } //構造程式碼塊