线程同步
来源:互联网 发布:上海公积金算法 编辑:程序博客网 时间:2024/06/14 22:19
线程同步
Java程序中可以存在多个线程,但是在处理多线程问题时,必须注意这样一个问题:当两个或多个线程同时访问同一个变量,并且一些线程需要修改这个变量。程序应对这样的问题做出处理,否则可能发生混乱,比如一个工资管理负责人正在修改雇员的工资表,而一些雇员也正在领取工资,如果允许这样做必然初夏 混乱。因此,工资管理负责人正在修改工资表(包括他喝杯茶休息一会),将不允许任何雇员领取工资,也就是说这些雇员必须等待。
所谓线程同步就是若干个线程都需要使用一个synchronized(同步)修饰的方法,即程序中的若干个线程都需要使用一个方法,而这个方法用synchronized给予了修饰,多个线程调用synchronized方法必须遵守同步机制。
线程同步机制:当一个线程A使用synchronized方法时,其他线程想使用这个synchronized方法时就必须等待,直到线程A使用完该synchronized方法。
在使用多线程解决许多实际问题时,可能要吧某些修改数据的方法用方法用关键字synchronized来修饰,即使用同步机制。
下面的例子中有两个线程:会计和出纳,他俩共同拥有一个账本,他俩都可以使用saveOrTake(int amount)方法对账本进行访问,会计使用saveOrTake(int amount)方法时,向账本上写入存钱记录;出纳使用saveOrTake(int amount)方法时,向账本写入取钱记录。因此,当会计正在使用saveOrTake(int amount)时,出纳被禁止使用,反之也是这样。比如,会计使用saveOrTake(int amount)时,在账本上存入300万元,但在存入这笔钱时,每存入100万,就喝口茶,那么会计喝茶休息时,存钱这件事还没结束,即会计还没有使用saveOrTake(int amount)方法,出纳仍不能使用saveOrTake(int amount);出纳使用saveOrTake(int amount)时,在账本上取出150万元,但在取出这笔钱时,每取出50万元,就喝口茶,那么出纳喝茶休息时,会计不能使用saveOrTake(int amount),也就是说,程序要保证其中一人使用saveOrTake(int amount)时,另一个人将必须等待,即saveOrTake(int amount)方法应当是一个synchronized方法。
例子:
Example12_7.java
package com.liu;public class Example12_7 { public static void main(String[] args) { Bank bank=new Bank(); bank.setMoney(200); Thread accountant,cashier; accountant=new Thread(bank); cashier=new Thread(bank); accountant.setName("会计"); cashier.setName("出纳"); accountant.start(); cashier.start(); }}
Bank.java
package com.liu;public class Bank implements Runnable{ int money=200; public void setMoney(int n){ money=n; } public void run(){ if(Thread.currentThread().getName().equals("会计")) saveOrTake(300); else if(Thread.currentThread().getName().equals("出纳")) saveOrTake(150); } public synchronized void saveOrTake(int amount){//注意这里是同步即有synchronized if(Thread.currentThread().getName().equals("会计")){ for(int i=1;i<=3;i++){ money=money+amount/3; System.out.println(Thread.currentThread().getName()+"存入"+amount/3+",账上有"+money+"万,休息一会再存"); try{Thread.sleep(1000); }catch(InterruptedException e){} } }else if(Thread.currentThread().getName().equals("出纳")){ for(int i=1;i<=3;i++){ money=money-amount/3; System.out.println(Thread.currentThread().getName()+"取出"+amount/3+",账上有"+money+"万,休息一会在取"); try{ Thread.sleep(1000); }catch(InterruptedException e){} } } }}
其运行结果:(一条一条输出到控制台,可以自己尝试运行查看效果)
当Bank.java 去掉saveOrTake方法的同步修饰synchronized时,观察运行结果。
(存在问题,请自己实际操作,两条同时输出,结果有问题)
- 线程同步--线程同步--线程同步--线程同步--线程同步
- 线程同步
- 线程同步
- 线程同步
- 线程同步
- 线程同步
- 线程同步
- 线程同步
- 线程同步
- 线程同步
- 线程同步
- 线程同步
- 线程同步
- 线程同步
- 线程同步
- 线程同步
- 线程同步
- 线程同步
- MySQL中B+Tree索引原理
- Gradle实现多渠道打包(不同资源文件打不同的包)
- Redis的使用方法
- Summary on Structured Data and their algorithms with OOL perspective
- 排序算法之归并排序
- 线程同步
- 打印星号
- 工作日常--记录今天提交了N次代码然后最后还是请教前端老大解决的一个自己觉得很傻逼的问题
- SSD目标识别在Spyder下实现
- Day8之面向对象复习1
- 更新CentOS内核后删除旧内核
- Finding relation and pattern--Influence of Mathematics: formal inferring with concepts
- 171124 逆向-线程环境块(TEB)
- 访问单个节点的删除