线程同步
* 异步编程模型和同步编程模拟的区别?
- 有T1和T2 两个线程
> 异步编程模型:T1线程执行T1的,T2线程执行T2的,谁也不等谁
> 同步编程模型:T1和T2 线程执行,当T1线程必须等T2线程执行结束后才能执行,这是同步编程模型
-
什么时候需要同步?
- 为了数据的安全 例如:同一银行卡同时取款
尽管降低了应用程序的效率,但是有时候为了保证数据是安全的必须加入同步机制.
线程同步机制使程序(等同)变成了单线程。
-
线程同步需要哪些条件?
- 必须是多线程环境
- 多线程环境共享同一个数据
- 共享的数据涉及到修改操作
-
使用线程同步机制,保护数据安全
-
使用 synchronized(共享对象) {
把需要同步的代码放到该同步语句块中
}
-
* synchronized 的原理?
> t1线程执行中遇到了synchronized 关键字,就回去找synchronized中的共享对象所持有的对象锁(每个对象都有对象锁有0和1两个值),如果找到了该对象的对象锁,则进入同步语句块中执行程序,当同步语句块中的
代码执行结束之后,t1线程会归还对象锁。
> 在t1线程执行同步语句块的过程中,如果t2线程也过来执行,也遇到了synchronized关键字,所以也会去找synchronized*享对象的对象锁,但是此时该对象锁正在被t1使用,所提t2线程只能在此等候t1线程归还
对象锁之后才能拿到对象锁进入同步语句块执行代码。
- synchronized也**可以**加到成员方法上
public synchronized void withdrow(double money) {}
-
代码实例
//线程的同步异步 public class ThreadTest11 { public static void main(String[] args) { //创建一个账户 Account account=new Account("608521478",5000); //创建线程 Processor_11 processor_11=new Processor_11(account); // 将同一个账户传进去 Thread thread1=new Thread(processor_11); Thread thread2=new Thread(processor_11); //启动线程 thread1.start(); thread2.start(); } }
//线程类
class Processor_11 implements Runnable{
//创建成员变量 账户
Account act;
//构造方法
Processor_11(){}
Processor_11(Account act){
this.act=act;
}
// 重写run方法
@Override
public void run() {
act.withDraw(1000);
}
}
//银行 账户类
class Account{
//属性
private String actNo;
private double balance;
//构造方法
public Account(){}
public Account (String actNo,double balance){
this.actNo=actNo;
this.balance=balance;
}
//getter and setter方法
public String getActNo() {
return actNo;
}
public void setActNo(String actNo) {
this.actNo = actNo;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
//取款的方法
public void withDraw(double money){ //对当前账户进行取款操作
//把需要同步的代码,放到同步语句块中
synchronized (this){
//取款后的余额
double after=balance-money;
//更新余额
this.setBalance(after);
System.out.println("取款1000成功,余额为:"+this.getBalance()+"元");
}
}
}