java的同步块_Java 同步块
Java同步塊用來(lái)標(biāo)記一個(gè)方法或一個(gè)代碼塊為同步的。Java同步塊可以用來(lái)避免競(jìng)態(tài)。
Java同步關(guān)鍵字
在 Java 中使用 synchronized 來(lái)標(biāo)記同步塊。一個(gè)同步塊是同步在某些對(duì)象上。同一個(gè)對(duì)象上的所有同步塊只能有一個(gè)線程執(zhí)行里面的代碼。其他線程試圖進(jìn)入同步塊都會(huì)被阻塞,直到同步塊中的現(xiàn)成離開(kāi)同步塊。
synchronized 可以用來(lái)標(biāo)記 4 種不同的同步塊:
實(shí)例方法
靜態(tài)方法
實(shí)例方法中的代碼塊
靜態(tài)代碼中的代碼塊
這些同步塊都同步在不同的對(duì)象上。視情況去使用它。
同步的實(shí)例方法
public synchronized void add(int value) {
this.count += value;
}
一個(gè)同步實(shí)例方法是同步在擁有該方法的實(shí)例上。同步實(shí)例方法中只能有一個(gè)線程可以執(zhí)行里面的方法。如果有多個(gè)實(shí)例,每個(gè)實(shí)例只能有一個(gè)線程去執(zhí)行同步實(shí)例方法,也就是一個(gè)實(shí)例一個(gè)線程。
同步靜態(tài)方法
public static synchronized void add(int value) {
count += value;
}
同步靜態(tài)方法同步在類(lèi)的類(lèi)對(duì)象上。因?yàn)?JVM 中每個(gè)類(lèi)只能有一個(gè)類(lèi)對(duì)象。只有一個(gè)線程可以執(zhí)行同一個(gè)類(lèi)中的同步靜態(tài)方法。
一個(gè)類(lèi)只能有一個(gè)線程,不管是執(zhí)行哪一個(gè)同步靜態(tài)方法。
實(shí)例方法中的代碼塊
有時(shí)候,可以不需要把整個(gè)方法同步,可以把方法的一部分同步。比如下面的代碼:一個(gè)不同步的方法中包含同步的代碼塊
public void add(int value) {
synchronized(this) {
this.count += value;
}
}
上面的示例代碼使用同步塊構(gòu)造器來(lái)標(biāo)記代碼塊是同步的。這個(gè)代碼執(zhí)行起來(lái)和同步方法一樣。
下面的代碼執(zhí)行效果是一樣的
public class MyClass {
public synchronized void log1(String msg1, String msg2) {
log.writeln(msg1);
log.writeln(msg2);
}
public viod log2(String msg1, String msg2) {
synchronized(this) {
log.writeln(msg1);
log.writeln(msg2);
}
}
}
如果第二個(gè)同步塊不是同步在this實(shí)例對(duì)象上,那么兩個(gè)方法可以被線程同時(shí)執(zhí)行。
同步靜態(tài)代碼塊
public class MyClass {
public static synchronized void log1(String msg1, String msg2) {
log.writeln(msg1);
log.writeln(msg2);
}
public static viod log2(String msg1, String msg2) {
synchronized(MyClass.class) {
log.writeln(msg1);
log.writeln(msg2);
}
}
}
這些方法都同步在類(lèi)上。
如果第二個(gè)同步塊不是同步在MyClass.class這個(gè)對(duì)象上。那么這兩個(gè)方法可以同時(shí)被線程訪問(wèn)。
Java 同步代碼例子
public class Counter {
long count = 0;
public synchronized void add(long value) {
this.count += value;
}
}
``java
public class CounterThread extends Thread {
protected Counter counter = null;
public CounterThread(Counter counter) {
this.counter = counter;
}
public void run() {
for (int i = 0; i < 10; i++) {
counter.add(i);
}
}
}
``java
public class Example {
public static void main(String[] args) {
Counter counter = new Counter();
Thread threadA = new CounterThread(counter);
Thread threadB = new CounterThread(counter);
threadA.start();
threadB.start();
}
}
當(dāng)線程創(chuàng)建的時(shí)候,都傳入了相同的 Counter 實(shí)例。Counter.add() 是同步實(shí)例方法。所以每次只能有一個(gè)線程可以執(zhí)行該方法。另外一個(gè)線程只能等待它執(zhí)行完才能去執(zhí)行方法。
如果兩個(gè)線程持有的不是同一個(gè) Counter 實(shí)例的話(huà),就不會(huì)有這個(gè)問(wèn)題。
public class Example {
public static void main(String[] args) {
Counter counterA = new Counter();
Counter counterB = new Counter();
Thread threadA = new CounterThread(counterA);
Thread threadB = new CounterThread(counterB);
threadA.start();
threadB.start();
}
}
QA
Q:
如果一個(gè)對(duì)象有多個(gè)方法加了synchronized,那么該對(duì)象有幾把鎖?
A:
對(duì)象鎖是在一個(gè)類(lèi)的對(duì)象上加的的鎖,只有一把,不管有幾個(gè)方法進(jìn)行了同步。
這些同步方法都共有一把鎖,只要一個(gè)線程獲得了這個(gè)對(duì)象鎖,其他的線程就不能訪問(wèn)該對(duì)象的任何一個(gè)同步方法。
總結(jié)
以上是生活随笔為你收集整理的java的同步块_Java 同步块的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: final在java中怎么用_Java中
- 下一篇: java向量数组异常,数组中空异常指针的