個(gè)人對(duì)java中對(duì)象鎖與類鎖的一些理解與實(shí)例
(https://www.cnblogs.com/houzheng/p/9084026.html)
一? 什么是對(duì)象鎖
對(duì)象鎖也叫方法鎖蒙秒,是針對(duì)一個(gè)對(duì)象實(shí)例的,它只在該對(duì)象的某個(gè)內(nèi)存位置聲明一個(gè)標(biāo)識(shí)該對(duì)象是否擁有鎖,所有它只會(huì)鎖住當(dāng)前的對(duì)象挨稿,而并不會(huì)對(duì)其他對(duì)象實(shí)例的鎖產(chǎn)生任何影響,不同對(duì)象訪問(wèn)同一個(gè)被synchronized修飾的方法的時(shí)候不會(huì)阻塞,
例如:
public?class?MyObject {
????private?synchronized?void?method1(){
????????try?{
????????????System.out.println(Thread.currentThread().getName());
????????????Thread.sleep(4000);
????????}?catch?(InterruptedException e) {
????????????e.printStackTrace();
????????}
????}
????//synchronized修飾為同步方法,如果先調(diào)用method1,則4秒后才會(huì)調(diào)用method2
????//如果不用synchronized修飾,則可以直接異步調(diào)用,沒(méi)有影響
????private?void?method2(){
????????System.out.println(Thread.currentThread().getName());
????}
}
創(chuàng)建一個(gè)類,synchronized修飾普通方法,即為對(duì)象鎖,那么這個(gè)時(shí)候,多個(gè)線程訪問(wèn)同一個(gè)對(duì)象實(shí)例的這個(gè)方法時(shí),是會(huì)同步的,并且只有一個(gè)線程執(zhí)行完,另一個(gè)線程才會(huì)執(zhí)行:
public?static?void?main(String[] args) {
????????//創(chuàng)建一個(gè)對(duì)象
????????MyObject myObject=new?MyObject();
????????Thread t1=new?Thread (new?Runnable() {
????????????@Override
????????????public?void?run() {
????????????????myObject.method1();
????????????}
????????},"t1");
????????Thread t2=new?Thread (new?Runnable() {
????????????@Override
????????????public?void?run() {
????????????????myObject.method1();
????????????}
????????},"t2");
????????t1.start();
????????t2.start();
????}
即,打印t14秒之后,t2才會(huì)打印,因?yàn)閮蓚€(gè)線程調(diào)用的是同一個(gè)對(duì)象實(shí)例的方法,即同一把鎖,所有會(huì)同步執(zhí)行
而如果是不同對(duì)象實(shí)例的話,則沒(méi)有影響,因?yàn)閮蓚€(gè)線程調(diào)用的是不同實(shí)例的鎖方法,即不是同一把鎖,沒(méi)有關(guān)系,所以會(huì)正常輸出,不會(huì)同步
public?static?void?main(String[] args) {
????????//創(chuàng)建兩個(gè)對(duì)象
????????MyObject myObject=new?MyObject();
????????MyObject myObject01=new?MyObject();
????????Thread t1=new?Thread (new?Runnable() {
????????????@Override
????????????public?void?run() {
????????????????myObject.method1();
????????????}
????????},"t1");
????????Thread t2=new?Thread (new?Runnable() {
????????????@Override
????????????public?void?run() {
????????????????myObject01.method1();
????????????}
????????},"t2");
????????t1.start();
????????t2.start();
????}
二 對(duì)象鎖的幾種形式以及應(yīng)用案例
1?synchronized修飾普通方法屬于對(duì)象鎖,
2,
synchronized修飾的代碼塊傳入this也屬于對(duì)象鎖
應(yīng)用:減小鎖粒度,第二種形式就比較好,比如A線程調(diào)用一個(gè)同步方法需要很長(zhǎng)時(shí)間,那么B就要等待很長(zhǎng)時(shí)間,這個(gè)時(shí)候可以將必須同步的代碼使用synchronized代碼塊,
?不需要同步的先執(zhí)行,節(jié)約資源
?三 類鎖
類鎖是鎖住整個(gè)類舅世,當(dāng)有多個(gè)線程來(lái)聲明這個(gè)類的對(duì)象時(shí)候?qū)?huì)被阻塞哗伯,直到擁有這個(gè)類鎖的對(duì)象唄銷毀或者主動(dòng)釋放了類鎖,這個(gè)時(shí)候在被阻塞的線程被挑選出一個(gè)占有該類鎖剧浸,聲明該類的對(duì)象。其他線程繼續(xù)被阻塞住
(上面百度的),即一句話,不管多少個(gè)對(duì)象,多少個(gè)對(duì)象,共用一把鎖,且只有一把,不管怎么調(diào)用,都會(huì)同步
上面方法加static變類鎖:
private?static?synchronized?void?method1(){
????????try?{
????????????System.out.println(Thread.currentThread().getName());
????????????Thread.sleep(4000);
????????}?catch?(InterruptedException e) {
????????????e.printStackTrace();
????????}
????}
這個(gè)時(shí)候無(wú)論線程調(diào)用的是多少個(gè)對(duì)象實(shí)例的方法,都會(huì)同步
四 類鎖形式
1 synchronized修飾靜態(tài)方法屬于類鎖
2