標籤:同步鎖 列印 不同 company -- 它的 判斷 執行個體 []
一個對象裡面如果有多個synchronized方法,某一個時刻內,只要一個線程去調用其中的一個synchronized方法了,其它的線程都只能等待,換句話說,某一個時刻內,只能有唯一一個線程去訪問這些synchronized方法鎖的是當前對象this,被鎖定後,其它的線程都不能進入到當前對象的其它的synchronized方法
加個普通方法後發現和同步鎖無關
換成兩個對象後,不是同一把鎖了,情況立刻變化。
都換成靜態同步方法後,情況又變化
所有的非靜態同步方法用的都是同一把鎖——執行個體對象本身,也就是說如果一個執行個體對象的非靜態同步方法擷取鎖後,該執行個體對象的其他非靜態同步方法必須等待擷取鎖的方法釋放鎖後才能擷取鎖,可是別的執行個體對象的非靜態同步方法因為跟該執行個體對象的非靜態同步方法用的是不同的鎖,所以毋須等待該執行個體對象已擷取鎖的非靜態同步方法釋放鎖就可以擷取他們自己的鎖。
所有的靜態同步方法用的也是同一把鎖——類對象本身,這兩把鎖是兩個不同的對象,所以靜態同步方法與非靜態同步方法之間是不會有競態條件的。但是一旦一個靜態同步方法擷取鎖後,其他的靜態同步方法都必須等待該方法釋放鎖後才能擷取鎖,而不管是同一個執行個體對象的靜態同步方法之間,還是不同的執行個體對象的靜態同步方法之間,只要它們同一個類的執行個體對象!
package com.company;/* * 題目:判斷列印的 "one" or "two" ? * * 1. 兩個普通同步方法,兩個線程,標準列印, 列印? //one two * 2. 新增 Thread.sleep() 給 getOne() ,列印? //one two * 3. 新增普通方法 getThree() , 列印? //three one two * 4. 兩個普通同步方法,兩個 Number 對象,列印? //two one * 5. 修改 getOne() 為靜態同步方法,列印? //two one * 6. 修改兩個方法均為靜態同步方法,一個 Number 對象? //one two * 7. 一個靜態同步方法,一個非靜態同步方法,兩個 Number 對象? //two one * 8. 兩個靜態同步方法,兩個 Number 對象? //one two * * 線程八鎖的關鍵: * ①非靜態方法的鎖預設為 this, 靜態方法的鎖為 對應的 Class 執行個體 * ②某一個時刻內,只能有一個線程持有鎖,無論幾個方法。 */public class TestThread8Monitor { public static void main(String[] args) { Number number = new Number(); Number number2 = new Number(); new Thread(() -> number.getOne()).start(); new Thread(() -> {// number.getTwo(); number2.getTwo(); }).start();// new Thread(() -> number.getThree()).start(); }}class Number { static synchronized void getOne() {//Number.class try { Thread.sleep(3000); } catch (InterruptedException e) { } System.out.println("one"); } synchronized void getTwo() {//this System.out.println("two"); } public void getThree() { System.out.println("three"); }}
java多線程 -- 線程八鎖