Java语言的
关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻
最多只有一个
线程执行这段代码。当两个并发线程访问同一个对象object中的这个加锁
同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。然而,当一个线程访问object的一个加锁代码块时,另一个线程仍然可以访问该object中的非加锁代码块。
Note:
当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞
1.方法声明时使用,放在范围
caozuofu.html" target="_blank">操作符(public等)之后,返回类型声明(void等)之前.这时,线程获得的是成员锁,即一次只能有一个线程进入该方法,其他线程要想在此时调用该方法,只能排队等候,当前线程(就是在synchronized方法内部的线程)执行完该方法后,别的线程才能进入.
例如:
public synchronized void synMethod(){
//方法体
}
如
在线程t1中有语句obj.synMethod(); 那么由于synMethod被synchronized修饰,在执行该语句前, 需要先获得调用者obj的对象锁, 如果其他线程(如t2)已经锁定了obj (可能是通过obj.synMethod,也可能是通过其他被synchronized修饰的方法obj.otherSynMethod锁定的obj), t1需要等待直到其他线程(t2)释放obj, 然后t1锁定obj, 执行synMethod方法. 返回之前之前释放obj锁.
2.对某一代码块使用,synchronized后跟括号,括号里是变量,这样,一次只有一个线程进入该代码块.此时,线程获得的是成员锁
class="java">
public class SynchronizedField {
private static Double balance = 100.0;
public static void main(String[] args) {
lockField();
}
public static void lockField() {
Thread withDrawThread = new WithdrawThread(10.0);
Thread depositThread = new Thread(new DepositThread(10.0));
withDrawThread.start();
depositThread.start();
}
private static final class WithdrawThread extends Thread {
private Double amount;
public WithdrawThread(Double amount) {
this.amount = amount;
}
public void run() {
synchronized (balance) {
System.out.println("Before withdrawing " + amount + ", the balance is " + balance);
balance -= amount;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Withdrew " + amount + ", the balance is " + balance);
}
}
}
private static final class DepositThread implements Runnable {
private Double amount;
public DepositThread(Double amount) {
this.amount = amount;
}
public void run() {
synchronized (balance) {
System.out.println("Before depositing " + amount + ", the balance is " + balance);
balance += amount;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Deposited " + amount + ", the balance is " + balance);
}
}
}
}
public class SynchronizedMethod {
private static Double balance = 100.0;
public static void main(String[] args) {
lockMethod();
}
public static void lockMethod() {
Thread depositThread1 = new Thread(new DepositThread(10.0));
Thread depositThread2 = new Thread(new DepositThread(10.0));
depositThread1.start();
depositThread2.start();
}
private static final class DepositThread implements Runnable {
private Double amount;
public DepositThread(Double amount) {
this.amount = amount;
}
public void run() {
deposit(amount);
}
}
public static synchronized void deposit(Double amount) {
System.out.println("Before depositing " + amount + ", the balance is " + balance);
balance += amount;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Deposited " + amount + ", the balance is " + balance);
}
}
Notes:
deposit方法不能写在DepositThread里