java并发编程 (一)synchronized关键字的使用

在多个人对同一个程序进行访问时,可能会因为没有对该段程序进行并发处理,导致结果出现非预期结果

下面以一个存钱取钱的程序为例:(此处不考虑手续费!!大笑

package com.robert.bean; public class BankAccount { private int cardMoney = 1000; private int cashMoney = 1000; //存款 public void deposit(int number) { cashMoney = cashMoney - number; System.out.println("存款: 当前现金为:"+cashMoney+"$"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } cardMoney = cardMoney + number; System.out.println("存款:当前卡上金额为:"+cardMoney+"$"); } //取款 public void withdrawl(int number) { cashMoney = cashMoney + number; System.out.println("取款: 当前现金为:"+cardMoney+"$"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } cardMoney = cardMoney - number; System.out.println("取款: 当前卡上金额为:"+cashMoney+"$"); } public int getAmount() { return cardMoney + cashMoney; } }
package com.robert.test; import com.robert.bean.BankAccount; public class TestSynchronized implements Runnable { BankAccount bankAccount = new BankAccount(); public static void main(String[] args) { TestSynchronized testSync = new TestSynchronized(); Thread thread1 = new Thread(testSync); Thread thread2 = new Thread(testSync); thread1.start(); thread2.start(); } public void run() { for(int i=0;i<20;i++) { bankAccount.deposit(50); bankAccount.withdrawl(40); } System.out.println("总金额为:"+bankAccount.getAmount()); } } 卡上有1000元,手上有1000元现金

现在进行存钱取钱操作,理论上不管怎么操作 卡上的钱+现金=2000

但是运行该程序你会发现,会有总金额不是2000的结果

显然说明该程序有误!

而通过给方法加关键字synchronized就能解决这个小问题。

修改后的程序如下所示

package com.robert.bean; public class BankAccount { private int cardMoney = 1000; private int cashMoney = 1000; //存款 public synchronized void deposit(int number) { cashMoney = cashMoney - number; System.out.println("存款: 当前现金为:"+cashMoney+"$"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } cardMoney = cardMoney + number; System.out.println("存款:当前卡上金额为:"+cardMoney+"$"); } //取款 public synchronized void withdrawl(int number) { cashMoney = cashMoney + number; System.out.println("取款: 当前现金为:"+cardMoney+"$"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } cardMoney = cardMoney - number; System.out.println("取款: 当前卡上金额为:"+cashMoney+"$"); } public synchronized int getAmount() { return cardMoney + cashMoney; } }
在此通过这个小例子对该关键字进行简单的介绍:

在java中synchronized有两种方法:

1 synchronized方法

2 synchronized声明

对于加过synchronized关键字的方法会产生两种影响

(1) 当一个线程正在执行一个synchronized的方法时,对于同一对象的调用该方法的其他线程将会被阻塞,直到第一个线程执行完毕。

(2)当一个synchronized的方法存在时,那么该方法就会同调用该方法的对象的其他调用之间建立happens-before关系,以使其他的线程对当前对象可见。


转载

原文出自:http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

如有问题请指出,谢谢。








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值