本文介绍java最基本的同步方式,即使用synchronized关键字来控制一个方法的并发访问,如果一个对象已用synchronized关键字声明,那么只有一个执行线程允许去访问它,其它试图访问这个对象的线程将被挂起,直到第一个线程访问完毕。

   下面通过一个小例子来学习这个概念,公司向银行存钱,取钱场景。

  1:创建Account的账号类,它是银行账户的模型,只有一个双精度浮点型属性,balance.

  2:实现balance的get set 方法。

  3:实现AddAmount()方法,将传入的数量加到余额balance中,并且在同一时间只允许一个线程去改变这个值,使用synchronized关键字。

  4:实现SubtractAmount()方法,将传入的数量从余额balance中扣除,并且在同一时间只允许一个线程去改变这个值。

  具体代码:

    

 public class Account {

     /**
* Balance of the bank account
*/
private double balance; /**
* Returns the balance of the account
* @return the balance of the account
*/
public double getBalance() {
return balance;
} /**
* Establish the balance of the account
* @param balance the new balance of the account
*/
public void setBalance(double balance) {
this.balance = balance;
} /**
* Add an import to the balance of the account
* @param amount import to add to the balance
*/
public synchronized void addAmount(double amount) {
double tmp=balance;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
tmp+=amount;
         balance=tmp;
} /**
* Subtract an import to the balance of the account
* @param amount import to subtract to the balance
*/
public synchronized void subtractAmount(double amount) {
double tmp=balance;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
tmp-=amount;
balance=tmp;
} }

  5:实现一个ATM模拟类Bank,它使用subtractAmount()方法对账户的余额进行扣除,实现Runabl接口。

   具体代码:

    

 public class Bank implements Runnable {

     /**
* The account affected by the operations
*/
private Account account; /**
* Constructor of the class. Initializes the account
* @param account The account affected by the operations
*/
public Bank(Account account) {
this.account=account;
} /**
* Core method of the Runnable
*/
public void run() {
for (int i=0; i<100; i++){
account.subtractAmount(1000);
}
} }

  6:实现公司模拟类,调用addAmount()方法进行存钱,实现Runabl接口。

  具体代码:

  

 public class Company implements Runnable {

     /**
* The account affected by the operations
*/
private Account account; /**
* Constructor of the class. Initializes the account
* @param account the account affected by the operations
*/
public Company(Account account) {
this.account=account;
} /**
* Core method of the Runnable
*/
public void run() {
for (int i=0; i<100; i++){
account.addAmount(1000);
}
}

  7:在主方法中调用测试:通过线程的join方法,在存期那,取钱线程模拟完毕后打印出结构。

  

 public class Main {

     /**
* Main method of the example
* @param args
*/
public static void main(String[] args) {
// Creates a new account ...
Account account=new Account();
// an initialize its balance to 1000
account.setBalance(1000); // Creates a new Company and a Thread to run its task
Company company=new Company(account);
Thread companyThread=new Thread(company);
// Creates a new Bank and a Thread to run its task
Bank bank=new Bank(account);
Thread bankThread=new Thread(bank); // Prints the initial balance
System.out.printf("Account : Initial Balance: %f\n",account.getBalance()); // Starts the Threads
companyThread.start();
bankThread.start(); try {
// Wait for the finalization of the Threads
companyThread.join();
bankThread.join();
// Print the final balance
System.out.printf("Account : Final Balance: %f\n",account.getBalance());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

  结果,相同时间内,存与取执行后应该是相等的。如果我们在方法中不去使用synchronized关键字,那么得出的结果就不对了。

  

  Account : Initial Balance: 1000.000000
  Account : Final Balance: 1000.000000

    

Java并发编程实战(使用synchronized实现同步方法)的更多相关文章

  1. 【Java并发编程实战】-----synchronized

    在我们的实际应用当中可能经常会遇到这样一个场景:多个线程读或者.写相同的数据,访问相同的文件等等.对于这种情况如果我们不加以控制,是非常容易导致错误的.在java中,为了解决这个问题,引入临界区概念. ...

  2. 【Java并发编程实战】—–synchronized

    在我们的实际应用其中可能常常会遇到这样一个场景:多个线程读或者.写相同的数据,訪问相同的文件等等.对于这样的情况假设我们不加以控制,是非常easy导致错误的. 在java中,为了解决问题,引入临界区概 ...

  3. Java并发编程实战——读后感

    未完待续. 阅读帮助 本文运用<如何阅读一本书>的学习方法进行学习. P15 表示对于书的第15页. Java并发编程实战简称为并发书或者该书之类的. 熟能生巧,不断地去理解,就像欣赏一部 ...

  4. 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport

    在上篇博客([Java并发编程实战]----- AQS(二):获取锁.释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起:在释放锁后,需要唤醒该线程的继任节点 ...

  5. 【Java并发编程实战】-----“J.U.C”:ReentrantLock之一简介

    注:由于要介绍ReentrantLock的东西太多了,免得各位客官看累,所以分三篇博客来阐述.本篇博客介绍ReentrantLock基本内容,后两篇博客从源码级别分别阐述ReentrantLock的l ...

  6. 【java并发编程实战】-----线程基本概念

    学习Java并发已经有一个多月了,感觉有些东西学习一会儿了就会忘记,做了一些笔记但是不系统,对于Java并发这么大的"系统",需要自己好好总结.整理才能征服它.希望同仁们一起来学习 ...

  7. java并发编程实战学习(3)--基础构建模块

    转自:java并发编程实战 5.3阻塞队列和生产者-消费者模式 BlockingQueue阻塞队列提供可阻塞的put和take方法,以及支持定时的offer和poll方法.如果队列已经满了,那么put ...

  8. 《java并发编程实战》笔记

    <java并发编程实战>这本书配合并发编程网中的并发系列文章一起看,效果会好很多. 并发系列的文章链接为:  Java并发性和多线程介绍目录 建议: <java并发编程实战>第 ...

  9. 《Java并发编程实战》文摘

    更新时间:2017-06-03 <Java并发编程实战>文摘,有兴趣的朋友可以买本纸质书仔细研究下. 一 线程安全性 1.1 什么是线程安全性 当多个线程访问某个类时,不管运行时环境采用何 ...

  10. Java并发编程实战.笔记十一(非阻塞同步机制)

    关于非阻塞算法CAS. 比较并交换CAS:CAS包含了3个操作数---需要读写的内存位置V,进行比较的值A和拟写入的新值B.当且仅当V的值等于A时,CAS才会通过原子的方式用新值B来更新V的值,否则不 ...

随机推荐

  1. php示例代码之使用MySQLi接口

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...

  2. servlet 学习(一)

    一.Servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术. Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向 ...

  3. Oracle shutdown immediate遭遇ORA-24324 ORA-24323 ORA-01089

    一数据库服务器执行shutdown immediate时,遇到了下面ORA错误,如下所示: $ sqlplus / as sysdba   SQL*Plus: Release 10.2.0.4.0 - ...

  4. 清理DBA_DATAPUMP_JOBS中的孤立数据泵作业

    今天在重构数据库时(将表空间中的表.索引转移到其它表空间)时,发现有两个奇怪的对象SYS_EXPORT_FULL_01.SYS_EXPORT_FULL_02搜索了一下,发现这个可能是EXPDP导出异常 ...

  5. JSP连接数据库

    1.将c3p0-0.9.5.2.jar/mchange-commons-java-0.2.11.jar/ojdbc6.jar三个包放在WEB-INF的lib文件夹下,将web.xml文件放到WEB-I ...

  6. 按要求编写Java应用程序。 (1)创建一个叫做机动车的类: 属性:车牌号(String),车速(int),载重量(double) 功能:加速(车速自增)、减速(车速自减)、修改车牌号,查询车的载重量。 编写两个构造方法:一个没有形参,在方法中将车牌号设置“XX1234”,速 度设置为100,载重量设置为100;另一个能为对象的所有属性赋值; (2)创建主类: 在主类中创建两个机动车对象。 创建第

    package com.hanqi.test; public class jidongche { private String chepaihao;//车牌号 private int speed;// ...

  7. dotNet使用HttpWebRequest模拟浏览器

    在编写网络爬虫时,HttpWebRequest几乎可以完成绝大多数网站的抓取,为了更好的使用这一技术,我将常用的几个功能进行了封装,以方便调用.这个类已经在多个项目中得到使用,主要解决了Cookies ...

  8. python极客学院爬虫V1

    定向爬取极客学院视频,原本只有年费VIP只能下载,经过分析,只要找个免费体验VIP即可爬取所有视频 涉及的基本技术:python xpath 正则 com+ 通过python调用迅雷从组件,实现自动创 ...

  9. Linux 学习001

    遇到的问题一: xxx is not in the sudoers file.This incident will be reported.的解决方法 1.切换到root用户下,怎么切换就不用说了吧, ...

  10. C语言(函数)学习之index、rindex

    函数定义:char *index(const char *s, int c); 头文件:    #include strings.h 函数说明:index()用来找出参数s 字符串中第一个出现的参数c ...