java并发编程学习6--同步--synchronized关键字
来源:互联网 发布:软件过了试用期 编辑:程序博客网 时间:2024/05/22 10:33
【条件竞争: 在多线程的开发中,两个及其以上的线程需要共享统一数据的存取。如果两个线程存取相同的对象,并且每一个线程都调用一个修改该对象状态的方法, 根据线程访问数据的顺序,可能会出现错误的数据结果,这种现象成为条件竞争。因为修改对象状态的方法并不是一个原子操作,通常步骤是: 1.读取当前状态值到线程工作内存。 2.在线程工作内存中修改状态值。 3.将修改后的状态值重新写入主内存。 而问题往往就是有多个线程同时在执行步骤2。【措施: 有两种机制代码受并发访问的干扰: 1.synchronized关键字。 2.Reentrantlock类。【synchronized关键字: java中每个对象都有一个内部锁。如果一个方法是用synchronized关键字修声明的,那么对象的锁将保护整个方法,也就是说要调用该方法,线程必须获得 对象内部锁。内部锁有如下的特点: 1.不能中断正在试图获得锁的线程。 2.试图获得锁不能设置超时时间。 3.只有一个条件:要么获得,要么等待,没有粒度更细的控制。
【例子: 下面的代码表示多个线程修改同一个对象造成数据失误的情况:public class Sync { private int value; void add(){ this.value ++; } int getValue(){ return this.value; } public static void main(String[] args) { for (int i = 0; i <30 ; i++) { Sync s = new Sync(); List<CompletableFuture> cfs = new ArrayList<>(); cfs.add(CompletableFuture.runAsync(() -> s.add())); cfs.add(CompletableFuture.runAsync(() -> s.add())); cfs.add(CompletableFuture.runAsync(() -> s.add())); //等待子线程执行完毕 CompletableFuture.allOf(cfs.toArray(new CompletableFuture[cfs.size()])).join(); System.out.println(s.getValue()); } }}现在使用synchronized关键字修饰add()看看:数据正常。【注意: 如果我们在同步的时候需要判断,切记将条件判断放在同步代码块之中,如果在外部判断,很有可能出现:
1.第一个线程通过条件判断2.第二个线程获得cpu,并修改了共享对象3.第一个线程再次获得cpu此时已经不满足条件,但是代码在向下执行,于是出现异常的情况。例如转账的例子:public class Account { //账户金额 private int amount; public Account(int amount){ this.amount = amount; } //转账 public synchronized void trans(Account to,int value){ //条件判断处于同步代码中!!!!!!if(amount - value < 0){ throw new RuntimeException("钱不够了!"); } this.amount -= value; to.addAmount(value); System.out.println("转账成功"); } public void addAmount(int amount){ this.amount += amount; } public int getAmount(){ return this.amount; } public static void main(String[] args) { Account from = new Account(100); Account to1 = new Account(0); Account to2 = new Account(0); List<CompletableFuture> cfs = new ArrayList<>(); cfs.add(CompletableFuture.runAsync(() -> from.trans(to1,100))); cfs.add(CompletableFuture.runAsync(() -> from.trans(to2,100))); CompletableFuture.allOf(cfs.toArray(new CompletableFuture[cfs.size()])).join(); System.out.println(from.getAmount()); System.out.println(to1.getAmount()); System.out.println(to2.getAmount()); }}
阅读全文
0 0
- java并发编程学习6--同步--synchronized关键字
- Java并发编程之同步关键字synchronized
- JAVA并发编程3_线程同步之synchronized关键字
- java并发编程---synchronized关键字
- Java并发编程:synchronized关键字解析
- Java 多线程并发编程之 Synchronized 关键字
- Java 多线程并发编程之 Synchronized 关键字
- Java 多线程并发编程之 Synchronized 关键字
- Java并发编程:synchronized多线程同步详解
- 【并发编程】Java同步块synchronized
- java并发编程-线程同步之synchronized
- Java 并发编程(四)线程同步关键字volatile和synchronized
- java并发编程(6)--synchronized
- 并发编程四:Synchronized关键字
- 并发编程学习总结(七) :java中synchronized关键字使用详解(1)
- JAVA并发编程学习笔记之synchronized
- JAVA并发编程学习笔记之synchronized
- JAVA并发编程学习笔记之synchronized
- python基础
- JDBC连接Oracle数据库
- linux下网卡bonding配置
- 优化
- 浅析python 中__name__ = '__main__' 的作用
- java并发编程学习6--同步--synchronized关键字
- Linux下 erlang/otp 20.0安装
- 轻松使用ESP8266
- HTTP协议,一篇就够了
- Ubuntu下apt-get命令详解
- 设计模式——工厂模式(php)
- 引导页和viewpager
- JaCoCo在Eclipse、Maven中的使用
- 深度学习之什么是神经网络