多线程的3种同步方法

未同步:

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 块中释放(这是释放外部资源的最好的地方)。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容