java进阶(38)--线程安全
2021-06-06 09:04
标签:sys div 设置 nts 在线 span 线程 运行 star 文档目录: 一、概念 二、解决方案 三、举例说明 ---------------------------------------分割线:正文-------------------------------------------------------- 一、概念 关注数据在多线程并发时安全问题,共享数据有修改的行为。 二、解决方案 1、线程排队执行,不能并发,即线程同步机制。 2、使用synchronized(){}线程同步代码块,()内填写需要同步的共享对象 3、局部变量永远不存在线程安全问题,因为局部变量是不会共享的 三、举例说明 1、编写程序模拟两个线程同时对同一个账户进行去取款操作 (1)变成账户类 (2)编写账户线程类 (3)测试类进行取款操作 (4)查看运行结果,一定几率出现钱被取完,余额未更新,出现线程安全问题 2、改进代码,使用线程同步机制来解决以上问题 (1)加入synchronized ()线程同步代码块 ()内需要填写多线程共享的数据,才能达到多线程排队。 改进后再次执行,多线程不会并发 (2)whithdraw调用时候增加,synchronized ()线程同步代码块,扩大了同步范围,执行效率变低 执行效果同上:多线程不会并发 (3)将实例方法使用synchronized 缺点:一定需要锁this,整个方法体都需要同步,可能会扩大同步范围导致程序效率过低 有点:代码比较少,简介 java进阶(38)--线程安全 标签:sys div 设置 nts 在线 span 线程 运行 star 原文地址:https://www.cnblogs.com/mrwhite2020/p/14608861.html 1 package JAVAADVANCE;
2
3 public class Account {
4 //账户与余额
5 private String actNo;
6 private double balance;
7
8 public Account(String actNo, double balance) {
9 this.actNo = actNo;
10 this.balance = balance;
11 }
12
13 public String getActNo() {
14 return actNo;
15 }
16
17 public void setActNo(String actNo) {
18 this.actNo = actNo;
19 }
20
21 public double getBalance() {
22 return balance;
23 }
24
25 public void setBalance(double balance) {
26 this.balance = balance;
27 }
28 //取款
29 public void withdraw(double money){
30 //取款之前的余额
31 double before=this.getBalance();
32 //取款之后的余额
33 double after = before-money;
34 //更新余额
35 this.setBalance(after);
36 }
37
38 }
1 package JAVAADVANCE;
2
3 public class AccountThread extends Thread {
4 //两个线程必须共享同一个账户对象
5 private Account act;
6 //通过构造方法传递过来的账户对象
7 public AccountThread(Account act){
8 this.act=act;
9 }
10 @Override
11 public void run() {
12 //run方法执行表示取款操作
13 //假设取款5000
14 double money=5000;
15 //取款
16 act.withdraw(money);
17 System.out.println(Thread.currentThread().getName()+"对账户"+act.getActNo()+"取款成功,余额为:"+act.getBalance());
18 }
19 }
1 package JAVAADVANCE;
2
3 public class TestAdvance38TestThreadSafe01 {
4 public static void main(String[] args) {
5 //创建账户对象,只创建一个
6 Account act=new Account("act-001",10000);
7 //创建两个线程
8 Thread t1=new AccountThread(act);
9 Thread t2=new AccountThread(act);
10 //设置name
11 t1.setName("t1");
12 t2.setName("t2");
13 //启动线程取款
14 t1.start();
15 t2.start();
16 }
17
18 }
t2对账户act-001取款成功,余额为:5000.0
t1对账户act-001取款成功,余额为:5000.0
1 //取款
2 public void withdraw(double money){
3 //增加线程同步机制,里面是线程同步代码块
4 synchronized (this){
5 //取款之前的余额
6 double before=this.getBalance();
7 //取款之后的余额
8 double after = before-money;
9 try {
10 Thread.sleep(1000);
11 } catch (InterruptedException e) {
12 e.printStackTrace();
13 }
14 //更新余额
15 this.setBalance(after);
16 }
17
18 }
t1对账户act-001取款成功,余额为:5000.0
t2对账户act-001取款成功,余额为:0.0
1 @Override
2 public void run() {
3 //run方法执行表示取款操作
4 //假设取款5000
5 double money=5000;
6 //取款
7 synchronized (act){
8 act.withdraw(money);}
9 System.out.println(Thread.currentThread().getName()+"对账户"+act.getActNo()+"取款成功,余额为:"+act.getBalance());
10 }
1 //取款
2 public synchronized void withdraw(double money){
3 //增加线程同步机制,里面是线程同步代码块
4 // synchronized (this){
5 //取款之前的余额
6 double before=this.getBalance();
7 //取款之后的余额
8 double after = before-money;
9 try {
10 Thread.sleep(1000);
11 } catch (InterruptedException e) {
12 e.printStackTrace();
13 }
14 //更新余额
15 this.setBalance(after);
16 }
下一篇:Python基础语法2