java并发系列——基本线程同步(一)
2015-12-31 00:03
399 查看
一、介绍
在并发编程中常见的多个线程共享同一资源,比如多个线程读或些相同的数据库,或访问同一个文件等,这些共享资源在多线程操作下会引起数据不安全问题,本章介绍一些机制来避免此问题。java提供了同步机制来实现一个临界区,当一个线程想要访问一个临界区,它使用其中的一个同步机制来找出是否有任何其他线程执行临界 区。如果没有,这个线程就进入临界区。否则,这个线程通过同步机制暂停直到另一个线程执行完临界区。当多个线程正在等待一个线程完成执行的一个临界 区,JVM选择其中一个线程执行,其余的线程会等待直到轮到它们。
二、同步方法
(1)、同步的概念Java中如何使用一个最基本的同步方法,即使用 synchronized关键字来控制并发访问方法。只有一个执行线程将会访问一个对象中被synchronized关键字声明的方法。如果另一个线程试图访问同一个对象中任何被synchronized关键字声明的方法,它将被暂停,直到第一个线程结束方法的执行。
换句话说,每个方法声明为synchronized关键字是一个临界区,Java只允许一个对象执行其中的一个临界区。
(2)、实例说明
下面介绍一个银行取款和存款的例子来说明多个线程访问共同对象,在没有同步的方法下,会引起账户结果不正确。
1.Account类
public class Account { private double balance; public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } //增加balance的值的方法 public synchronized void addAmount(double amount){ double tmp=balance; try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } tmp+=amount; balance=tmp; } //减少balance的值的方法 public synchronized void subAmount(double amount){ double tmp=balance; try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } tmp-=amount; balance=tmp; } }
2.Bank类模拟ATM取款
public class Bank implements Runnable { public Account account; public Bank(Account account){ this.account=account; } @Override public void run() { for(int i=0;i<100;i++){ account.subAmount(100); } } }
3.Company类模拟存款
public class Company implements Runnable { public Account account; public Company(Account account){ this.account=account; } @Override public void run() { for(int i=0;i<100;i++){ account.addAmount(100); } } }
(3)、synchronized的其他特性
synchronized关键字不利于应用程序的性能,所以你必须仅在修改共享数据的并发环境下的方法上使用它。如果你有多个线程正在调用一个synchronized方法,在同一时刻只有一个线程执行它,而其他的线程将会等 待。如果这个操作没有使用synchronized关键字,所有线程可以在同一时刻执行这个操作,减少总的执行时间。如果你知道一个方法将不会被多个线程 调用,请不要使用synchronized关键字
(4)synchronized保护代码块
synchronized关键字以这样的方式来保护访问的共享数据,其余的操作留出此代码块,这将会获得更好的应用程序性能。这个目标就是让临界区(在同 一时刻可以被多个线程访问的代码块)尽可能短。我们已经使用了synchronized关键字来保护访问指令,将不使用共享数据的长操作留出此代码块。当 你以这个方式使用synchronized关键字,你必须通过一个对象引用作为参数。只有一个线程可以访问那个对象的synchronized代码(代码 块或方法)。
通常,我们将使用this关键字引用执行该方法的对象。
synchronized (this) {
}
相关文章推荐
- java中map集合类用法(hashmap用法)
- Eclipse + Gradle实现APK分包
- JAVA学习策略篇:学习JAVA的步骤
- Spring 事务回滚机制
- Spring AOP+事务控制
- Java多线程实现方式
- java线程状态
- 八皇后问题(经典回溯法)
- java 静态导入 import static
- day05-----------java 语言基础(基础语法)(传智视频)
- JAVA设计模式单例模式(懒汉式和饿汉式)
- java Executors介绍
- 给jdk写注释系列之jdk1.6容器(9)-Strategy设计模式之Comparable&Comparator接口
- java 多线程机制简单总结
- Java集合框架
- 插入排序
- Java枚举类型的小应用
- Spring MVC集成Tiles使用方法
- win10 jdk配置环境变量时的注意事项
- springmvc(1)DispatcherServlet源码简单解析