Day13_02_线程同步(synchronized)

线程同步

  *  异步编程模型和同步编程模拟的区别?

     - 有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()+"元");
             }

        }
   }
上一篇:委托实现信用卡用户定时还款功能


下一篇:JAVA_TEST01