我是靠谱客的博主 超帅板凳,这篇文章主要介绍synchronized锁run()的问题,现在分享给大家,希望可以做个参考。

在一个模拟银行取钱的例子上,直接把synchronized加到了run方法上,发现并没有解决并发带来的不安全性。

class GetMoney extends Thread{
private Account account;
private Integer needMoney;
public GetMoney(Account account, Integer needMoney) {
this.account = account;
this.needMoney = needMoney;
}
@Override
public synchronized void run() {
if(account.getMoney()-needMoney<0){
System.out.println(Thread.currentThread().getName()+"取钱时,钱不够!!!!!!!!!!!!");
return;
}
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
account.setMoney(account.getMoney()-needMoney);
System.out.println(account.getName()+"还有"+account.getMoney());
System.out.println(Thread.currentThread().getName()+"手上有"+needMoney);
}
}

证明有多个线程都能访问到run方法,并没有起到锁的效果,发现当继承Thread父类的时候,每次创建都会new一个新的对象,相当于每个线程都有一个synchronized锁,锁的是this对象,所以无法解决不安全性的问题。
第一种解决方法:将线程改为继承runnable接口

这样在主线程中创建线程时,就只需要一个对象,解决了这个问题

public static void main(String[] args) {
Account account=new Account(600,"公司账户");
GetMoney getMoney=new GetMoney(account,400);
new Thread(getMoney,"小红").start();
new Thread(getMoney,"小明").start();
}

第二种解决方法:使用对象锁代码块synchronized(obj){}的方式

直接锁account对象,来实现时间段内只有一个线程在操作这一对象

synchronized (account){
if(account.getMoney()-needMoney<0){
System.out.println(Thread.currentThread().getName()+"取钱时,钱不够!!!!!!!!!!!!");
return;
}
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
account.setMoney(account.getMoney()-needMoney);
System.out.println(account.getName()+"还有"+account.getMoney());
System.out.println(Thread.currentThread().getName()+"手上有"+needMoney);
}

最后

以上就是超帅板凳最近收集整理的关于synchronized锁run()的问题的全部内容,更多相关synchronized锁run()内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(229)

评论列表共有 0 条评论

立即
投稿
返回
顶部