java的同步块_Java 同步块
Java同步塊用來標記一個方法或一個代碼塊為同步的。Java同步塊可以用來避免競態。
Java同步關鍵字
在 Java 中使用 synchronized 來標記同步塊。一個同步塊是同步在某些對象上。同一個對象上的所有同步塊只能有一個線程執行里面的代碼。其他線程試圖進入同步塊都會被阻塞,直到同步塊中的現成離開同步塊。
synchronized 可以用來標記 4 種不同的同步塊:
實例方法
靜態方法
實例方法中的代碼塊
靜態代碼中的代碼塊
這些同步塊都同步在不同的對象上。視情況去使用它。
同步的實例方法
public synchronized void add(int value) {
this.count += value;
}
一個同步實例方法是同步在擁有該方法的實例上。同步實例方法中只能有一個線程可以執行里面的方法。如果有多個實例,每個實例只能有一個線程去執行同步實例方法,也就是一個實例一個線程。
同步靜態方法
public static synchronized void add(int value) {
count += value;
}
同步靜態方法同步在類的類對象上。因為 JVM 中每個類只能有一個類對象。只有一個線程可以執行同一個類中的同步靜態方法。
一個類只能有一個線程,不管是執行哪一個同步靜態方法。
實例方法中的代碼塊
有時候,可以不需要把整個方法同步,可以把方法的一部分同步。比如下面的代碼:一個不同步的方法中包含同步的代碼塊
public void add(int value) {
synchronized(this) {
this.count += value;
}
}
上面的示例代碼使用同步塊構造器來標記代碼塊是同步的。這個代碼執行起來和同步方法一樣。
下面的代碼執行效果是一樣的
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);
}
}
}
如果第二個同步塊不是同步在this實例對象上,那么兩個方法可以被線程同時執行。
同步靜態代碼塊
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);
}
}
}
這些方法都同步在類上。
如果第二個同步塊不是同步在MyClass.class這個對象上。那么這兩個方法可以同時被線程訪問。
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();
}
}
當線程創建的時候,都傳入了相同的 Counter 實例。Counter.add() 是同步實例方法。所以每次只能有一個線程可以執行該方法。另外一個線程只能等待它執行完才能去執行方法。
如果兩個線程持有的不是同一個 Counter 實例的話,就不會有這個問題。
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:
如果一個對象有多個方法加了synchronized,那么該對象有幾把鎖?
A:
對象鎖是在一個類的對象上加的的鎖,只有一把,不管有幾個方法進行了同步。
這些同步方法都共有一把鎖,只要一個線程獲得了這個對象鎖,其他的線程就不能訪問該對象的任何一個同步方法。
總結
以上是生活随笔為你收集整理的java的同步块_Java 同步块的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: final在java中怎么用_Java中
- 下一篇: java统计各空气质量最大值_空气质量历