本博客每一個(gè)小標(biāo)題下的內(nèi)容獨(dú)立且完整常空,如只是想了解某個(gè)小標(biāo)題下的內(nèi)容汞斧,只需前往看該小標(biāo)題即可瞪浸。
1. 多線程并發(fā)訪問(wèn)同一個(gè)對(duì)象的同一個(gè)非靜態(tài)synchronized方法
完整代碼:
public class myClass {
public static void main(String[] args) {
final TestClass testClass = new TestClass();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
testClass.methodA();
}
}, "線程1");
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
testClass.methodA();
}
}, "線程2");
thread1.start();
thread2.start();
}
}
class TestClass {
/**
* 普通同步方法A
*/
public void methodA() {
synchronized (this) {
for (int i = 0; i < 4; i++) {
System.out.println(Thread.currentThread().getName() + "正在執(zhí)行methodA:" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
小標(biāo)題已經(jīng)準(zhǔn)確表達(dá)了上面這塊代碼的意思生真,運(yùn)行結(jié)果如下:
由執(zhí)行結(jié)果可知,兩個(gè)線程中其中一個(gè)線程執(zhí)行完才會(huì)執(zhí)行第二個(gè)線程捺宗。結(jié)論就是柱蟀,多個(gè)線程并發(fā)訪問(wèn)同一個(gè)對(duì)象的同一個(gè)非靜態(tài)synchronized方法時(shí),先獲取到鎖的線程執(zhí)行完畢后才會(huì)執(zhí)行其它線程蚜厉。也就是說(shuō)synchronized(this)
這種鎖可以鎖定一個(gè)非靜態(tài)synchronized方法长已,只讓獲取了該鎖的線程執(zhí)行,其它線程在該線程未執(zhí)行完畢之前不能執(zhí)行
2. 多線程并發(fā)訪問(wèn)同一個(gè)對(duì)象的不同非靜態(tài)synchronized方法
完整代碼:
public class myClass {
public static void main(String[] args) {
final TestClass testClass = new TestClass();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
testClass.methodA();
}
}, "線程1");
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
testClass.methodB();
}
}, "線程2");
thread1.start();
thread2.start();
}
}
class TestClass {
/**
* 普通同步方法A
*/
public void methodA() {
synchronized (this) {
for (int i = 0; i < 4; i++) {
System.out.println(Thread.currentThread().getName() + "正在執(zhí)行methodA:" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 普通同步方法B
*/
public void methodB() {
synchronized (this) {
for (int i = 0; i < 4; i++) {
System.out.println(Thread.currentThread().getName() + "正在執(zhí)行methodB:" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
運(yùn)行結(jié)果如下:
由執(zhí)行結(jié)果可知昼牛,兩個(gè)線程中其中一個(gè)線程執(zhí)行完才會(huì)執(zhí)行第二個(gè)線程术瓮。結(jié)論是多個(gè)線程并發(fā)訪問(wèn)同一個(gè)對(duì)象的不同非靜態(tài)synchronized方法時(shí),先獲取到鎖的線程執(zhí)行完畢后才會(huì)執(zhí)行其它線程贰健。也就是說(shuō)胞四,synchronized(this)
這種鎖鎖定的范圍是該對(duì)象的所有非靜態(tài)synchronized方法,而不單單是獲取了該鎖的線程正在執(zhí)行的非靜態(tài)synchronized方法
3. 多線程并發(fā)訪問(wèn)同一個(gè)對(duì)象的不同方法伶椿,一個(gè)是非靜態(tài)synchronized方法辜伟,一個(gè)是非靜態(tài)非synchronized方法
完整代碼:
public class myClass {
public static void main(String[] args) {
final TestClass testClass = new TestClass();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
testClass.methodA();
}
}, "線程1");
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
testClass.methodC();
}
}, "線程2");
thread1.start();
thread2.start();
}
}
class TestClass {
/**
* 普通同步方法A
*/
public void methodA() {
synchronized (this) {
for (int i = 0; i < 4; i++) {
System.out.println(Thread.currentThread().getName() + "正在執(zhí)行methodA:" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 普通方法,非同步
*/
public void methodC() {
for (int i = 0; i < 4; i++) {
System.out.println(Thread.currentThread().getName() + "正在執(zhí)行methodC:" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
運(yùn)行結(jié)果如下:
由執(zhí)行結(jié)果可知脊另,兩個(gè)線程并發(fā)執(zhí)行导狡,沒(méi)有先后順序。結(jié)論是多個(gè)線程并發(fā)訪問(wèn)同一個(gè)對(duì)象的不同方法時(shí)偎痛,一個(gè)是非靜態(tài)synchronized方法旱捧,一個(gè)是非靜態(tài)非synchronized方法,這兩線程并發(fā)運(yùn)行踩麦。也就是說(shuō)廊佩,synchronized(this)
這種鎖鎖定的是該對(duì)象的所有非靜態(tài)synchronized方法,并不會(huì)鎖定該對(duì)象的非靜態(tài)非synchronized方法靖榕。
4. 多線程并發(fā)訪問(wèn)同一個(gè)對(duì)象的不同方法,一個(gè)是非靜態(tài)synchronized方法顽铸,一個(gè)是靜態(tài)synchronized方法
public class myClass {
public static void main(String[] args) {
final TestClass testClass = new TestClass();
// final TestClass testClassNext = new TestClass();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
testClass.methodA();
}
}, "線程1");
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
testClass.methodE();
}
}, "線程2");
thread1.start();
thread2.start();
}
}
class TestClass {
/**
* 普通同步方法A
*/
public void methodA() {
synchronized (this) {
for (int i = 0; i < 4; i++) {
System.out.println(Thread.currentThread().getName() + "正在執(zhí)行methodA:" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 靜態(tài)同步方法E
*/
public synchronized static void methodE() {
for (int i = 0; i < 4; i++) {
System.out.println(Thread.currentThread().getName() + "正在執(zhí)行methodE:" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
運(yùn)行結(jié)果如下:
由執(zhí)行結(jié)果可知茁计,兩個(gè)線程并發(fā)執(zhí)行,沒(méi)有先后順序谓松。結(jié)論是多個(gè)線程并發(fā)訪問(wèn)同一個(gè)對(duì)象的不同方法時(shí)星压,一個(gè)是非靜態(tài)synchronized方法,另一個(gè)是靜態(tài)synchronized方法鬼譬,這兩線程并發(fā)運(yùn)行娜膘。也就是說(shuō),优质,synchronized(this)
這種鎖鎖定的范圍是這個(gè)對(duì)象所有的非靜態(tài)synchronized方法竣贪,而靜態(tài)synchronized鎖鎖定的是該類的所有對(duì)象的所有靜態(tài)synchronized方法军洼,兩個(gè)鎖鎖的作用范圍不一樣,執(zhí)行起來(lái)就不會(huì)相互鎖定
5. 多線程并發(fā)訪問(wèn)同一個(gè)類不同對(duì)象的同一個(gè)非靜態(tài)synchronized方法
public class myClass {
public static void main(String[] args) {
final TestClass testClass = new TestClass();
final TestClass testClassNext = new TestClass();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
testClass.methodA();
}
}, "線程1");
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
testClassNext.methodA();
}
}, "線程2");
thread1.start();
thread2.start();
}
}
class TestClass {
/**
* 普通同步方法A
*/
public void methodA() {
synchronized (this) {
for (int i = 0; i < 4; i++) {
System.out.println(Thread.currentThread().getName() + "正在執(zhí)行methodA:" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
運(yùn)行結(jié)果如下:
由執(zhí)行結(jié)果可知演怎,兩個(gè)線程并發(fā)執(zhí)行匕争,沒(méi)有先后順序。結(jié)論是多個(gè)線程并發(fā)訪問(wèn)同一個(gè)類不同對(duì)象的同一個(gè)非靜態(tài)synchronized方法時(shí)爷耀,這兩線程并發(fā)運(yùn)行甘桑。也就是說(shuō),synchronized(this)
這種鎖鎖定的范圍是該對(duì)象的非靜態(tài)synchronized方法歹叮,而不能鎖定該類的另一個(gè)實(shí)例的非靜態(tài)synchronized方法跑杭。
6. 多線程并發(fā)訪問(wèn)同一個(gè)類的不同對(duì)象的同一個(gè)靜態(tài)synchronized方法
public class myClass {
public static void main(String[] args) {
final TestClass testClass = new TestClass();
final TestClass testClassNext = new TestClass();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
testClass.methodD();
}
}, "線程1");
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
testClassNext.methodD();
}
}, "線程2");
thread1.start();
thread2.start();
}
}
class TestClass {
/**
* 靜態(tài)同步方法D
*/
public synchronized static void methodD() {
for (int i = 0; i < 4; i++) {
System.out.println(Thread.currentThread().getName() + "正在執(zhí)行methodD:" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
運(yùn)行結(jié)果如下:
由執(zhí)行結(jié)果可知,兩個(gè)線程中其中一個(gè)線程執(zhí)行完才會(huì)執(zhí)行第二個(gè)線程咆耿。結(jié)論是多線程并發(fā)訪問(wèn)同一個(gè)類的不同對(duì)象的同一個(gè)靜態(tài)synchronized方法時(shí)德谅,先獲取到鎖的線程執(zhí)行完畢之后才會(huì)執(zhí)行下一個(gè)線程。也就是說(shuō)票灰,靜態(tài)synchronized鎖鎖定的范圍已經(jīng)不再是單個(gè)對(duì)象的靜態(tài)synchronized方法了女阀,而是所有對(duì)象的靜態(tài)synchronized方法。
上述所有情況的總結(jié)
在一個(gè)類對(duì)象范圍內(nèi)屑迂,非靜態(tài)synchronized鎖不僅鎖定當(dāng)前獲取該鎖的線程正在執(zhí)行的非靜態(tài)synchronized方法浸策,還會(huì)鎖定該對(duì)象的其他所有非靜態(tài)synchronized方法,但不會(huì)鎖定該對(duì)象的非靜態(tài)非synchronized方法惹盼、靜態(tài)非synchronized方法和靜態(tài)synchronized方法庸汗;
非靜態(tài)synchronized鎖作用范圍是在一個(gè)對(duì)象里,并不會(huì)干涉到其他線程調(diào)用該類的另一個(gè)對(duì)象的非靜態(tài)synchronized方法手报,而靜態(tài)synchronized鎖可以影響到其它對(duì)象蚯舱;
靜態(tài)synchronized鎖會(huì)鎖定該類的所有對(duì)象的所有靜態(tài)synchronized方法,但不會(huì)鎖定該類的所有對(duì)象的的靜態(tài)非synchronized方法掩蛤、非靜態(tài)synchronized方法枉昏、非靜態(tài)非synchronized方法;
非靜態(tài)synchronized鎖鎖定的是該類的一個(gè)實(shí)例對(duì)象揍鸟,靜態(tài)synchronized鎖鎖定的其實(shí)是該類的Class對(duì)象兄裂。