未同步:
Account.java(账户类)
package thread01;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Account {
private double balance;
private Lock accountLock=new ReentrantLock();
public double getBalance() {
return balance;
}
public void deposit(double money) {
double newBalance = balance + money;
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
balance = newBalance;
System.out.println("Account balance:"+balance);
}
}
AddMoneyThread.java(线程类)
package thread01;
public class AddMoneyThread implements Runnable {
private Account account;
private double money;
public AddMoneyThread(Account account, double money) {
this.account = account;
this.money = money;
}
@Override
public void run() {
account.deposit(money);
}
}
测试类
package thread01;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Test01 {
public static void main(String[] args) {
Account account=new Account();
ExecutorService service=Executors.newFixedThreadPool(100);
for(int i=0;i<100;i++){
service.execute(new AddMoneyThread(account, 1));
}
service.shutdown();
while(!service.isTerminated()){}
System.out.println("账户余额:"+account.getBalance());
}
}
测试结果:2,没有同步
</br>
</br>
</br>
同步有三种方法
方法1:修改Account.java中deposit方法,添加修饰符synchronized
package thread01;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Account {
private double balance;
private Lock accountLock=new ReentrantLock();
public double getBalance() {
return balance;
}
public synchronized void deposit(double money) {
double newBalance = balance + money;
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
balance = newBalance;
System.out.println("Account balance:"+balance);
}
}
方法2:AddMoneyThread.java中添加synchronized块
package thread01;
public class AddMoneyThread implements Runnable {
private Account account;
private double money;
public AddMoneyThread(Account account, double money) {
this.account = account;
this.money = money;
}
@Override
public void run() {
synchronized(account){
account.deposit(money);
}
}
}
方法3:Account.java,添加lock机制
package thread01;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Account {
private double balance;
private Lock accountLock=new ReentrantLock();
public double getBalance() {
return balance;
}
public void deposit(double money) {
accountLock.lock();
try{
double newBalance = balance + money;
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
balance = newBalance;
}finally{
accountLock.unlock();
System.out.println("Account balance:"+balance);
}
}
}
面试题:简述synchronized 和java.util.concurrent.locks.Lock的异同?
答:Lock是Java 5以后引入的新的API,和关键字synchronized相比
主要相同点:Lock 能完成synchronized所实现的所有功能;
主要不同点:Lock有比synchronized更精确的线程语义和更好的性能,而且不强制性的要求一定要获得锁。synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且最好在finally 块中释放(这是释放外部资源的最好的地方)。