synchronized 同步方法/块

同步块对象同步方法能更细粒度的锁定内容java

 

同步锁:太大,容易形成效率低下,过小,锁不住web

线程安全synchronized   尽量锁定合理的范围(不是锁代码,而是锁数据)安全

双重检测并发

package com.wxh.syn;
//线程安全synchronized   尽量锁定合理的范围(不是锁代码,而是锁数据)
public class Web12306 implements Runnable {
    int numberKey = 10;
    boolean flag = true;
    public static void main(String[] args) {
        Web12306 web = new Web12306();
        new Thread(web,"马超").start();
        new Thread(web,"关羽").start();
        new Thread(web,"曹操").start();
    }
    public void run() {
             test7();
    }
    //尽量锁定合理范围,最合理的方法,双重检测
        private void test7() {    
            while(flag) {
                if(numberKey <= 0) {    //判断还有没有票
                    flag = false;
                    return;
                }
                synchronized(this) {    //由于对象为flag 和numberkey,锁住一个对象是不安全的,
                if(numberKey <= 0) {        //判断临界值,如当只有最后一张票时
                    flag = false;
                    return;
                }
                
                
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"-->"+numberKey--);
                }     
            
            }
                }
    
        private void test5() {
            
            
            while(flag) {
                synchronized(this) {    // a,b,c 三个线程,a拿到锁,进行判断,释放锁,B拿到锁,释放锁,a此时在sleep,B也进入sleep,
                                            //但sleep结束,cpu调度可能先执行B,此时就会出现票数同时拿到
            if(numberKey <= 0) {
                flag = false;
                return;
            }
                }
                
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"-->"+numberKey--);
                
            
        }
        
            }
        private synchronized void test3() {
            while(true) {
            
            if(numberKey <= 0) {
                return;
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"-->"+numberKey--);
            
        }
        
            
    }
        private  void test2() {
            
            while(flag) {
                synchronized((Integer)numberKey) {    //由于对象为flag 和numberkey,锁住一个对象是不安全的,
                if(numberKey <= 0) {
                    flag = false;
                    return;
                }
                
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"-->"+numberKey--);
                }    
            
            }
                }
    
        private  void test() {
            
            while(true) {
                synchronized(this) {    //线程安全,由于this对象包括了numberkey和flag
            if(numberKey <= 0) {
                return;
            }
                
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"-->"+numberKey--);
                }
            
        }
        
            }
        }

            银行取钱,锁定银行帐号:app

package com.wxh.syn;

/**
 * synchronized 锁执行完毕以后,才释放锁
 * 由于银河存款100,可悲啊取走80后,剩余20不达到happy的他取钱90要求,return
 * @author Administrator
 *    代码块:更加精细控制
 */
public class UnsafeTest {
    public static void main(String[] args) {
         Account1 account = new Account1(170, "结婚礼金");
         Drawing1 you = new Drawing1(account, 80, "可悲啊");
         Drawing1 wif = new Drawing1(account, 90, "happy的他");
         you.start();
         wif.start();
        
    }
}

//建立银行帐户
class Account1{
    int money;
    String name;
    public Account1(int money, String name) {
        
        this.money = money;
        this.name = name;
    }
    
}

    //模拟取款
class Drawing1 extends Thread{
    Account1 account;    //取钱的帐户
    int Outmoney;        //取得钱数
    int pagemoney;        //取得总数
    
    
    public Drawing1(Account1 account, int outmoney,String name) {
        super(name);
        this.account = account;
        Outmoney = outmoney;
    }


    public void run() {
        test();
    }

    //目标锁定不对,应该锁定对象(银行帐号account)
    private  void test() {
        if(account.money <= 0) {    //提升性能的细节,由于每次线程进来都须要判断锁是否执行完以后再判断
            return;                            //而这一步提早判断当银行余额为0时,不须要执行如下代码,大大提升了并发量。
        }
        
        synchronized(account) {
        if(account.money -Outmoney <0) {
            return;
        }
        
        
//        try {
//            Thread.sleep(1000);
//        } catch (InterruptedException e) {
//            // TODO Auto-generated catch block
//            e.printStackTrace();
//        }
        account.money -= Outmoney;        //帐户余额
        pagemoney =  Outmoney;
        
        System.out.println(this.getName()+"--->帐户余额"+account.money);
        System.out.println(this.getName()+"--->口袋金额"+pagemoney);
        }                //synchronized 锁执行完毕以后,才释放锁
        
    }
}
相关文章
相关标签/搜索