欢迎光临散文网 会员登陆 & 注册

同步块性能优化的代码

2020-04-14 08:59 作者:小垃圾kiki  | 我要投稿
package cn.jd.syn;

/*
 * 线程安全:在并发时保证数据的正确性,同时保证效率尽可能高
 * synchronized
 * 1.同步方法(在方法上面加synchronized)
 * 2.同步块
 */

public class SynBlockTest03 {

    public static void main(String[] args) {
        //一份资源
        SynWeb12306  web=new SynWeb12306();
                //多个代理
                new Thread(web,"laoda").start();
                new Thread(web,"laoer").start();
                new Thread(web,"laosan").start();

    }

}
class SynWeb12306 implements Runnable{
    //票数
    private int ticketNums=3;
    private boolean flag=true;
    @Override
    public void run() {
        while(flag) {
            test5();
        }
        
    }
    //线程安全:尽可能锁定合理的范围(不是指的代码而是数据的完整性)
    //在多线程里面称为双重检测(主要考虑的就是临界值的问题)
    public  void test5() {
        //假设还有一张票,多个线程进来,这一块的代码拦不住
        if(ticketNums<=0) {//考虑的是没有票的情况      
            flag=false;
            return;
        }
        synchronized (this) {
            if(ticketNums<0) {//考虑的是最后一张票     
                flag=false;
                return;
            }
            //模拟网络延时
            try {
                Thread.sleep(200);  
                //进入了阻塞状态,然后200s以后我就重新等待CPU的调用
                //继续执行下面的代码
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"-->"+ticketNums--);
        }
        
    }
    //线程不安全   范围太小锁不住
    public  void test4() {
        synchronized (this) {
            if(ticketNums<0) {
                flag=false;
                return;
            }
        }
            //模拟网络延时
            try {
                Thread.sleep(200);  
                //进入了阻塞状态,然后200s以后我就重新等待CPU的调用
                //继续执行下面的代码
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"-->"+ticketNums--);
        
        
    }
    //线程不安全锁定失败  ticketNums对象在变(根本原因就是对象的地址发生了改变)   
    //    对象在变和对象的属性再变是两回事
    public  void test3() {
        synchronized ((Integer)ticketNums) {
            if(ticketNums<0) {
                flag=false;
                return;
            }
            //模拟网络延时
            try {
                Thread.sleep(200);  
                //进入了阻塞状态,然后200s以后我就重新等待CPU的调用
                //继续执行下面的代码
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"-->"+ticketNums--);
        }
        
    }
    
    
    
    
    //同步块    范围太大性能效率低下
    public  void test2() {
        synchronized (this) {
            if(ticketNums<0) {
                flag=false;
                return;
            }
            //模拟网络延时
            try {
                Thread.sleep(200);  
                //进入了阻塞状态,然后200s以后我就重新等待CPU的调用
                //继续执行下面的代码
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"-->"+ticketNums--);
        }
        
    }
    
    
    
    
    
    //线程安全,同步
    public synchronized void test1() {
        if(ticketNums<0) {
            flag=false;
            return;
        }
        //模拟网络延时
        try {
            Thread.sleep(200);  
            //进入了阻塞状态,然后200s以后我就重新等待CPU的调用
            //继续执行下面的代码
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"-->"+ticketNums--);
    }
    

}

同步块性能优化的代码的评论 (共 条)

分享到微博请遵守国家法律