synchronized關(guān)鍵字
主要用于修飾以下三種情況
一稼跳,修飾普通方法浸颓。
private synchronized void add(){}
eg
public class TestSync {
private int count;
public static void main(String[] args) {
final TestSync testSync=new TestSync();
new Thread(new Runnable() {
@Override
public void run() {
testSync.add();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
testSync.add();
}
}).start();
}
private synchronized void add(){
for (int i = 0; i <10 ; i++) {
System.out.println(Thread.currentThread().getName()+"--"+count++);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
輸出結(jié)果
可以看到第一個(gè)線程執(zhí)行完成了才會(huì)執(zhí)行第二個(gè)線程。如果沒(méi)有用synchronized修飾的話,結(jié)果會(huì)是兩個(gè)線程隨機(jī)調(diào)度逐工∶枞冢可自行實(shí)踐铝噩。
二,修飾代碼塊
在某些情況下稼稿,我們編寫的方法體可能比較大薄榛,同時(shí)存在一些耗時(shí)的操作,而需要同步的代碼又只有一小部分让歼,如果直接對(duì)整個(gè)方法進(jìn)行同步操作敞恋,可能會(huì)得不償失。
我們把a(bǔ)dd()方法改一下
private void add(){
//其他操作省略....
synchronized (this){
for (int i = 0; i <10 ; i++) {
System.out.println(Thread.currentThread().getName()+"--"+count++);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
得到的結(jié)果和上面例子的結(jié)果是一樣的谋右。假如該方法只有一個(gè)for循環(huán)硬猫。像這樣
private void add(){
synchronized (this){
for (int i = 0; i <10 ; i++) {
System.out.println(Thread.currentThread().getName()+"--"+count++);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
這樣和直接修飾方法是沒(méi)有區(qū)別的。
三改执,修飾靜態(tài)方法
靜態(tài)方法是類方法啸蜜,使用synchronized關(guān)鍵字修飾靜態(tài)方法得到的類鎖。類鎖和對(duì)象鎖不互斥辈挂,也就是說(shuō)多個(gè)線程分別調(diào)用
某個(gè)類的同步靜態(tài)方法和同步普通方法衬横,不會(huì)是同步的。
public class TestSync {
public static void main(String[] args) {
final TestSync testSync=new TestSync();
new Thread(new Runnable() {
@Override
public void run() {
delete();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
testSync.add();
}
}).start();
}
private synchronized void add(){
//其他操作省略....
for (int i = 0; i <10 ; i++) {
System.out.println("線程"+Thread.currentThread().getName()+"執(zhí)行次數(shù)--"+i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private synchronized static void delete(){
for (int i = 0; i <10 ; i++) {
System.out.println("線程"+Thread.currentThread().getName()+"執(zhí)行次數(shù)--"+i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
結(jié)果
多個(gè)線程調(diào)一個(gè)同步靜態(tài)方法终蒂,是互斥的蜂林。
public static void main(String[] args) {
final TestSync testSync=new TestSync();
final TestSync testSync2=new TestSync();
new Thread(new Runnable() {
@Override
public void run() {
delete();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
delete();
}
}).start();
}
private synchronized static void delete(){
for (int i = 0; i <10 ; i++) {
System.out.println("線程"+Thread.currentThread().getName()+"執(zhí)行次數(shù)--"+i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
結(jié)果如下圖,得出多
上面我們講到對(duì)象鎖拇泣,什么叫對(duì)象鎖呢噪叙,也就是一個(gè)對(duì)象只有一把鎖,拿到這個(gè)鎖才能調(diào)用被鎖的方法霉翔,我們?cè)囋噧蓚€(gè)對(duì)象
public class TestSync {
public static void main(String[] args) {
final TestSync testSync=new TestSync();
final TestSync testSync2=new TestSync();
new Thread(new Runnable() {
@Override
public void run() {
testSync2.add();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
testSync.add();
}
}).start();
}
private synchronized void add(){
//其他操作省略....
for (int i = 0; i <10 ; i++) {
System.out.println("線程"+Thread.currentThread().getName()+"執(zhí)行次數(shù)--"+i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private synchronized static void delete(){
for (int i = 0; i <10 ; i++) {
System.out.println("線程"+Thread.currentThread().getName()+"執(zhí)行次數(shù)--"+i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
結(jié)果
結(jié)果很明顯睁蕾,雖然這個(gè)add方法是同步的,但是我new了兩個(gè)對(duì)象债朵,調(diào)用的時(shí)候子眶,并不會(huì)互斥。
總結(jié):
synchronized關(guān)鍵一般代表的是對(duì)象鎖葱弟,一個(gè)對(duì)象只有一把鎖壹店,在同一個(gè)對(duì)象內(nèi),多個(gè)線程調(diào)用一個(gè)synchronized修飾的非靜態(tài)方法會(huì)互斥芝加。
如果修飾的是靜態(tài)方法硅卢,則得到的類鎖射窒,此時(shí)該方法相對(duì)于整個(gè)類都是同步的,對(duì)象鎖無(wú)關(guān)且不互斥将塑。
參考 https://blog.csdn.net/javazejian/article/details/72828483