@Java | Thread synchronized - [ 线程同步锁 基本使用]
生活随笔
收集整理的這篇文章主要介紹了
@Java | Thread synchronized - [ 线程同步锁 基本使用]
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
對實現了Runnable或者Callable接口類,可以通過多線程執行同一實例的run或call方法,那么對于同一實例中的局部變量(非方法變量)就會有多個線程進行更改或讀取,這就會導致數據不一致,synchronized(關鍵字)可以解決多線程共享數據同步的問題 修飾一個代碼塊:被修飾的代碼塊稱為同步語句塊,其作用的范圍是大括號{}括起來的代碼,作用的對象是調用這個代碼塊的對象 修飾一個非靜態方法:被修飾的方法稱為同步方法,其作用的范圍是整個方法,作用的對象是調用這個方法的對象 修改一個靜態的方法:其作用的范圍是整個靜態方法,作用的對象是這個類的所有對象 修改一個類:其作用的范圍是synchronized后面括號括起來的部分,作用主的對象是這個類的所有對象 高能提示:
No1 > synchronized修飾的非靜態方法:如果一個對象有多個synchronized方法,只要一個線程訪問了其中的一個synchronized方法,則這個線程所屬對象的其它線程不能同時訪問這個對象中任何一個synchronized方法
No2 > synchronized關鍵字是不能繼承的:基類的方法synchronized function(){}在繼承類中并不自動是synchronized function(){},而是變成了function(){}。繼承類需要你顯式的指定它的某個方法為synchronized方法,可以通過子類調用父類的同步方法來實現同步
No3 > 針對synchronized修飾代碼塊和非靜態方法,本質上鎖的是代碼塊或非靜態方法對應的對象(代碼塊是synchronized標注的變量,非靜態方法是所在類對應的實例),如果是不同的對象是可以同時訪問的
No4 > 實現同步是要很大的系統開銷作為代價的,甚至可能造成死鎖,所以盡量避免無謂的同步控制
No5 > 每個對象只有一個鎖(lock)與之相關聯
No6 > 在定義接口方法時不能使用synchronized關鍵字
No7 > 構造方法不能使用synchronized關鍵字,但可以使用synchronized代碼塊來進行同步
synchronized(o)修飾的代碼塊,其中o可以取值一個對象或者一個變量或者this亦或者Clz.class public class Sync implements Runnable {private byte[] lock = new byte[0];public void syncCode() {synchronized (lock) {// 同步代碼塊}}public void run .... } 注:零長度的byte數組對象創建起來將比任何對象都經濟,查看編譯后的字節碼,生成零長度的byte[]對象只需3條操作碼,而Object lock = new Object()則需要7行操作碼線程同步的目的是為了保護多個線程反問一個資源時對資源的破壞。 線程同步方法是通過鎖來實現,每個對象都有切僅有一個鎖,這個鎖與一個特定的對象關聯,線程一旦獲取了對象鎖,其他訪問該對象的線程就無法再訪問該對象的其他非同步方法 對于靜態同步方法,鎖是針對這個類的,鎖對象是該類的Class對象。靜態和非靜態方法的鎖互不干預。一個線程獲得鎖,當在一個同步方法中訪問另外對象上的同步方法時,會獲取這兩個對象鎖。 對于同步,要時刻清醒在哪個對象上同步,這是關鍵。 編寫線程安全的類,需要時刻注意對多個線程競爭訪問資源的邏輯和安全做出正確的判斷,對"原子"操作做出分析,并保證原子操作期間別的線程無法訪問競爭資源。 當多個線程等待一個對象鎖時,沒有獲取到鎖的線程將發生阻塞。 死鎖是線程間相互等待鎖鎖造成的,在實際中發生的概率非常的小,一旦程序發生死鎖,程序將死掉
synchronized使用說明
作用范圍
synchronized是Java中的關鍵字,是一種同步鎖。它修飾的對象有以下幾種:No1 > synchronized修飾的非靜態方法:如果一個對象有多個synchronized方法,只要一個線程訪問了其中的一個synchronized方法,則這個線程所屬對象的其它線程不能同時訪問這個對象中任何一個synchronized方法
No2 > synchronized關鍵字是不能繼承的:基類的方法synchronized function(){}在繼承類中并不自動是synchronized function(){},而是變成了function(){}。繼承類需要你顯式的指定它的某個方法為synchronized方法,可以通過子類調用父類的同步方法來實現同步
No3 > 針對synchronized修飾代碼塊和非靜態方法,本質上鎖的是代碼塊或非靜態方法對應的對象(代碼塊是synchronized標注的變量,非靜態方法是所在類對應的實例),如果是不同的對象是可以同時訪問的
No4 > 實現同步是要很大的系統開銷作為代價的,甚至可能造成死鎖,所以盡量避免無謂的同步控制
No5 > 每個對象只有一個鎖(lock)與之相關聯
No6 > 在定義接口方法時不能使用synchronized關鍵字
No7 > 構造方法不能使用synchronized關鍵字,但可以使用synchronized代碼塊來進行同步
1. 修飾一個代碼塊
public void syncCode(Object o) {synchronized (o) {// 同步代碼塊} } 上面的鎖就是o這個對象,當然多個線程同步需要保證o這個對象是同一個,這是有明確的對象作為鎖的情況,如果只是想單純的讓某一段代碼同步,并沒有明確的對象作為鎖,可以創建一個特殊的instance變量來充當鎖synchronized(o)修飾的代碼塊,其中o可以取值一個對象或者一個變量或者this亦或者Clz.class public class Sync implements Runnable {private byte[] lock = new byte[0];public void syncCode() {synchronized (lock) {// 同步代碼塊}}public void run .... } 注:零長度的byte數組對象創建起來將比任何對象都經濟,查看編譯后的字節碼,生成零長度的byte[]對象只需3條操作碼,而Object lock = new Object()則需要7行操作碼
2. 修飾一個非靜態方法
public synchronized void method() {// .....} 此時鎖的是調用這個同步方法的對象3. 修飾一個靜態方法
public synchronized static void method() {// .....} synchronized修飾的靜態方法鎖定的是這個類的所有對象4. 修飾類
public class Sync implements Runnable {public void syncCode() {synchronized (Sync.class) {// 同步代碼塊}}public void run .... } 和作用于靜態方法一樣,synchronized作用于一個類時,是給這個類加鎖,類的所有對象用的是同一把鎖總結
總結
以上是生活随笔為你收集整理的@Java | Thread synchronized - [ 线程同步锁 基本使用]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python认识if语句_python初
- 下一篇: java 多线程池_Java项目中,线程