• 多线程(3)


    1.为什么使用synchronized和java.util.concurrent.locks.Lock?

    1>线程不安全,因为线程是随机的,它可以随机访问你可见的共享变量。如果共享变量被修改,对另一个线程操作来说,它的数据就不准确

    2>数据不安全,数据被共享

    即共享变量、可见性和原子性

    3>指令重排序(as-if-serial)

     

       加锁,是只一个线程可以访问,其他线程等待访问的线程结束,后面的线程由cpu随机分配访问。

    *线程状态

    线程状态:创建->就绪->运行->死亡

    线程从就绪状态被唤醒,运行时,有其他线程正在运行且访问的是它要访问的内容,那么,它会阻塞。

    阻塞->就绪

    休眠状态:即等待(阻塞)状态

    运行时,如果cpu随机分配线程抢占了当前线程的资源,该线程进入就绪状态。

    public class Account {
    
        private long money = 0;//余额
        
        public Account(){}
        
        public long cunQian(int num){//存钱
            money  = money + num;
            return num;
        }
        
        public long quQian(int num){//取钱
             money = money - num;
             return num;
        }
        
        public long getMoney(){
            return money;
        }
    }
    import java.util.Random;
    
    public class Thread02 extends Thread{
    
        private Account acc = null;
        public Thread02(Account acc){
            this.acc = acc;
        }
        @Override
        public void run() {
            long cunQian = acc.cunQian(new Random().nextInt(1000));
            System.out.println("存了:"+cunQian+";账户内有:"+acc.getMoney());
            long quQian = acc.quQian(new Random().nextInt(1000));
            System.out.println("取了:"+quQian+";账户内有:"+acc.getMoney());
        }
    
    }

    无锁

    public class Thread02Main {
    
        public static void main(String[] args) {
            Account acc = new Account();
            Thread02 t1 = new Thread02(acc);
            Thread02 t2 = new Thread02(acc);
            Thread02 t3 = new Thread02(acc);
            t1.start();
            t2.start();
            t3.start();
            
        }
    }

     

    *无序且数据错误(效果和有锁比较)

    有锁

    import java.util.Random;
    
    public class Thread02 extends Thread{
    
        private Account acc = null;
        public Thread02(Account acc){
            this.acc = acc;
        }
        @Override
        public void run() {
            synchronized (acc) {
                long cunQian = acc.cunQian(new Random().nextInt(1000));
                System.out.println("存了:"+cunQian+";账户内有:"+acc.getMoney());
                long quQian = acc.quQian(new Random().nextInt(1000));
                System.out.println("取了:"+quQian+";账户内有:"+acc.getMoney());
            }
        }
    
    }
    public class Account {
    
        private long money = 0;
        
        public Account(){}
        
        public synchronized long cunQian(int num){//存钱
            money  = money + num;
            return num;
        }
        
        public synchronized long quQian(int num){//取钱
             money = money - num;
             return num;
        }
        
        public long getMoney(){
            return money;
        }
    }








    *先存后取,账户数据正确。负数是因为存取钱是随机数。
  • 相关阅读:
    【2021-05-18】人生十三信条
    【2021-05-17】打了第一针疫苗
    【2021-05-16】该工作时好好工作,该休息时好好休息
    【2021-05-15】人生十三信条
    【2021-05-14】要保持团队作战的模式
    【2021-05-13】罗马不是一天能建成的
    【2021-05-12】己所不欲勿施于人
    【2021-05-11】服务好了别人,也就服务好了自己
    二维区域和检索
    寻找重复数
  • 原文地址:https://www.cnblogs.com/zzlcome/p/11085343.html
Copyright © 2020-2023  润新知