zoukankan      html  css  js  c++  java
  • 多线程(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;
        }
    }








    *先存后取,账户数据正确。负数是因为存取钱是随机数。
  • 相关阅读:
    视图类,双缓冲,图片资源的显示
    偏好设置
    yii2安装遇到[InvalidArgumentException] Could not find package
    java 回调函数解读
    工具使用——神器mimikatz使用
    cve-2019-0708 远程桌面代码执行漏洞复现
    工具使用--sqlmap使用
    漏洞复现--通达OA前台任意用户伪造登录漏洞
    漏洞复现--cve-2020-1938 Apache tomcat 文件包含漏洞
    ThinkPad T480s 用户指南V4.0--更换键盘部分
  • 原文地址:https://www.cnblogs.com/zzlcome/p/11085343.html
Copyright © 2011-2022 走看看