synchronized可以鎖對(duì)象恰梢,代碼塊,類對(duì)象 藻烤,那么他們用起來會(huì)有區(qū)別嗎,這里我們用實(shí)際代碼來探究下
package com.example.hxk.thread.synchroized;
public class SyncTest1 {
// synchronized修飾非靜態(tài)方法
public synchronized void test1() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// synchronized代碼塊
public void test2() {
synchronized (this) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
SyncTest1 t1 = new SyncTest1();
new Thread(new Runnable() {
@Override
public void run() {
t1.test1();
}
}, "thread1").start();
new Thread(new Runnable() {
@Override
public void run() {
t1.test2();
}
}, "thread2").start();
}
}
運(yùn)行結(jié)果:
thread1 : 0
thread1 : 1
thread1 : 2
thread1 : 3
thread1 : 4
thread2 : 0
thread2 : 1
thread2 : 2
thread2 : 3
thread2 : 4
這里thread2會(huì)等thread1運(yùn)行完成才會(huì)開始運(yùn)行头滔,說明thread1和thread2請(qǐng)求的是同一把鎖,也就說明了 synchronized代碼塊鎖當(dāng)前對(duì)象和鎖非靜態(tài)方法怖亭,他們的效果是一樣的, 鎖的都是當(dāng)前對(duì)象坤检。
然后我們?cè)賮砜纯搭愭i兴猩,修改代碼如下
package com.example.hxk.thread.synchroized;
public class SyncTest1 {
// 修飾靜態(tài)方法
public static synchronized void test1() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// 修飾類對(duì)象
public void test2() {
synchronized (SyncTest1.class) {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
SyncTest1 t1 = new SyncTest1();
new Thread(new Runnable() {
@Override
public void run() {
SyncTest1.test1();
}
}, "thread1").start();
new Thread(new Runnable() {
@Override
public void run() {
t1.test2();
}
}, "thread2").start();
}
}
運(yùn)行結(jié)果:
thread1 : 0
thread1 : 1
thread1 : 2
thread1 : 3
thread1 : 4
thread2 : 0
thread2 : 1
thread2 : 2
thread2 : 3
thread2 : 4
這里可以看到thread2也是被thread1阻塞,所以他們持有的是同一把鎖早歇,也就說明synchronized修飾靜態(tài)方法和鎖類對(duì)象倾芝,他們的效果是一樣的。 接下來我們同時(shí)用類鎖和對(duì)象鎖試試箭跳,代碼如下
package com.example.hxk.thread.synchroized;
public class SyncTest1 {
// 修飾靜態(tài)方法
public static synchronized void test1() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// 修飾類對(duì)象
public synchronized void test2() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
SyncTest1 t1 = new SyncTest1();
new Thread(new Runnable() {
@Override
public void run() {
SyncTest1.test1();
}
}, "thread1").start();
new Thread(new Runnable() {
@Override
public void run() {
t1.test2();
}
}, "thread2").start();
}
}
運(yùn)行結(jié)果:
thread1 : 0
thread2 : 0
thread1 : 1
thread2 : 1
thread2 : 2
thread1 : 2
thread2 : 3
thread1 : 3
thread2 : 4
thread1 : 4
運(yùn)行結(jié)果是交替進(jìn)行的晨另,說明對(duì)象鎖和類鎖鎖的不是同一個(gè)鎖,他們是兩個(gè)鎖谱姓,互不影響
總結(jié):
1借尿,synchronized修飾在非靜態(tài)方法上和synchronized(this){} 同步代碼塊效果是一樣的
2,synchronized修飾在靜態(tài)方法上和 synchronized (SyncTest1.class) {} 同步代碼塊效果是一樣的
3屉来,synchronized修飾在非靜態(tài)方法表示鎖的是當(dāng)前對(duì)象路翻,修飾靜態(tài)方法表示鎖的是類對(duì)象(一個(gè)類在jvm中只有一個(gè)class對(duì)象)