java 线程同步控制_JAVA多线程同步 synchronized用法

Java的多线程是无序的,是由JVM来调度的。我们不能控制哪个线程先执行,但是可以用synchronized方法或者synchronized同步块,来控制线程在特定部分按顺序执行。

我们用银行取钱这个例子来说明synchronized的用法:创建一个银行类,里面写上存钱取钱的方法(存钱是正数,取钱是负数,我就只写一个方法了)

public class Bank

{

int money;

String account;

public Bank(String account, int money)

{

this.account = account;

this.money = money;

}

public void operatorMoney(int opmoney)

{

System.out.println(Thread.currentThread().getName() + ",欢迎来到银行办理业务");

this.money += opmoney;

System.out.println(Thread.currentThread().getName() + ",操作的金额为:" + opmoney + ",现在账户金额为:" + money);

System.out.println(Thread.currentThread().getName() + ",谢谢您的操作!!!");

}

}再写一个子类继承Thread类

public class OperatorThread extends Thread

{

Bank bank;

int opmoney;

public OperatorThread(String name, Bank bank, int opmoney) {

super(name);

this.bank=bank;

this.opmoney=opmoney;

}

public void run() {

this.bank.operatorMoney(opmoney);

}

}创建5个线程通过不同方式来存钱取钱。

public class Test

{

public static void main(String[] args)

{

Bank bank =new Bank("建设银行",5000);

OperatorThread p1 = new OperatorThread("微信支付", bank, -500);

OperatorThread p2 = new OperatorThread("Apple Pay", bank, 450);

OperatorThread p3 = new OperatorThread("支付宝支付", bank, -1000);

OperatorThread p4 = new OperatorThread("QQ支付", bank, -800);

OperatorThread p5 = new OperatorThread("银行卡支付", bank, 2500);

p1.start();

p2.start();

p3.start();

p4.start();

p5.start();

}

}

5个线程进入到可执行状态,我来run下看下结果

通过代码可以看到我卡上的余额初始值是5000,虽然最后的结果是没错,但是每次执行完账户金额都是不对的,这里就造成了一个安全问题,收到的消息和你实际操作的值不相等。

在这里我们就可以使用synchronized方法来让线程一个一个的执行,通过牺牲性能来提高安全性。将银行类中的operatorMoney方法修改为:

public synchronized void operatorMoney(int opmoney)

{

System.out.println(Thread.currentThread().getName() + ",欢迎来到银行办理业务");

this.money += opmoney;

System.out.println(Thread.currentThread().getName() + ",操作的金额为:" + opmoney + ",现在账户金额为:" + money);

System.out.println(Thread.currentThread().getName() + ",谢谢您的操作!!!");

}

这个时候的运行结果为:

我们可以看到现在的结果就是正常结果了,哪个线程先执行是我们不能决定的,但我们可以让它们一个一个的执行,大大提高了安全性。在这个基础上我们还可以对它进行优化,还是改变刚刚修改的operatorMoney方法:

public void operatorMoney(int opmoney)

{

System.out.println(Thread.currentThread().getName() + ",欢迎来到银行办理业务");

synchronized (this)

{

this.money += opmoney;

System.out.println(Thread.currentThread().getName() + ",操作的金额为:" + opmoney + ",现在账户金额为:" + money);

}

System.out.println(Thread.currentThread().getName() + ",谢谢您的操作!!!");

}

我们使用同步块对这段代码进行了优化,使线程只有在执行金额的加减时才一个一个的执行,结果如下:

可以看到这个同步块只是让同步块里的线程进行同步执行,欢迎语则是在一开始就出来了,提高了运行的性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值