显示锁

2 篇文章 0 订阅
2 篇文章 0 订阅

显示锁


  1. lock 接口和Synchronized比较
    Synchronized代码简洁,
    lock :获取锁可以被中断,超时获取锁,尝试的获取锁
  2. lock接口和核心方法
    lock():
    unlock()
    trylock()
    /**
     * 使用显示锁的范式
     */
    public class LockDome {
        private Lock lock = new ReentrantLock();
    private int count;
    public void increament() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }
    }
    
    
  3. 可重入锁ReentrantLock、所谓的公平和非公平
    可重入:获取锁的多次,锁重入一次,锁的数量+1 ,执行完这个方法执行-1 方法执行完毕为0
     public synchronized void test1() {
         count++;
         test1();
     }
     public synchronized void test2() {
         count++;
         test1();
     }
    
    公平锁:如果在时间上先对锁进行获取的请求一定先被满足
    非公平锁:如果在时间上先对锁进行获取的请求不先被满足
    非公平锁的效率一般比公平锁更高
    ReentrantLock 和syn都是排它锁,只允许一个线程访问,
  4. ReadWriteLock接口和读写锁ReetrantReadWriteLock
    读写锁:同一时刻,允许多个读线程同时访问,但是写线程访问的时候,所有的读和写都会阻塞
    读多,写少的情况下,可以使用读写锁
    用法 :
    商品类:

public class GoodsInfo {

    private String name;
    private int totalMoney;
    private int storeNumber;

    public GoodsInfo(String name, int totalMoney, int storeNumber) {
        this.name = name;
        this.totalMoney = totalMoney;
        this.storeNumber = storeNumber;
    }

    public int getTotalMoney() {
        return totalMoney;
    }

    public int getStoreNumber() {
        return storeNumber;
    }
    public  void changNubmer(int sellNumber){
        this.totalMoney += sellNumber*26;
        this.storeNumber -= sellNumber;
    }
}

业务类:


/**
 * 使用读写锁操作
 */
public class UseRwLock implements GoodsService {
    private GoodsInfo goodsInfo;
    //缺省   非公平锁
    private final ReadWriteLock lock = new ReentrantReadWriteLock();

    private final Lock getlock = lock.readLock();//读锁
    private final Lock writelock = lock.writeLock();//写锁

    public UseRwLock(GoodsInfo goodsInfo) {
        this.goodsInfo = goodsInfo;
    }

    @Override
    public GoodsInfo getNum() {
        getlock.lock();
        try {
            Thread.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            getlock.unlock();
        }
        return this.goodsInfo;
    }

    @Override
    public void setNum(int number) {
        getlock.lock();
        try {
            Thread.sleep(5);
            goodsInfo.changNubmer(number);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            getlock.unlock();
        }

    }
}

启动类:


public class BusiApp {
    static final int readWriteratio = 10;//读写线程的比例
    static final int minthreadcount = 3;//最少线程

    private static class GetThread implements Runnable {
        GoodsService goodsService;

        public GetThread(GoodsService goodsService) {
            this.goodsService = goodsService;
        }

        @Override
        public void run() {
            long start = System.currentTimeMillis();
            for (int i = 0; i < 100; i++) {
                goodsService.getNum();
            }
            System.out.println(Thread.currentThread().getName()+"   读取商品耗时 。。。。。: " + (System.currentTimeMillis() - start));
        }
    }  private static class SetThread implements Runnable {
        GoodsService goodsService;

        public SetThread(GoodsService goodsService) {
            this.goodsService = goodsService;
        }

        @Override
        public void run() {
            long start = System.currentTimeMillis();
            Random r = new Random();
            for (int i = 0; i < 10; i++) {



                    goodsService.setNum(r.nextInt(10));

            }
            System.out.println(Thread.currentThread().getName()+"   写商品耗时 。。。。。: " + (System.currentTimeMillis() - start));
        }
    }

    public static void main(String[] args) throws InterruptedException {
        GoodsInfo goodsInfo = new GoodsInfo("CPU",10000,10000);
        GoodsService goodsService = new UseSyn(goodsInfo);
        for (int i = 0; i < minthreadcount; i++) {
            Thread set = new Thread(new SetThread(goodsService));
            for (int j = 0; j < readWriteratio; j++) {
                Thread get = new Thread(new GetThread(goodsService));
                get.start();
            }
            Thread.sleep(100);
            set.start();
        }
    }
}

相比Syn效率提升非常明显
5. Condition 和lock实现等待通知


public class ExpressCond {
    public final static String CITY = "Shanghai";
    private int km; // 快递运输里程数
    private String site; // 快递到达地点
    private Lock kmlock = new ReentrantLock();
    private Lock sitelock = new ReentrantLock();
    private Condition kmcond = kmlock.newCondition();
    private Condition sitecond = sitelock.newCondition();

    public ExpressCond() {
    }

    public ExpressCond(int km, String site) {

        this.km = km;
        this.site = site;
    }

    //     变化公里数 然后通知处于wait状态并需要处理公里数的线程进行业务处理
    public void changKm() {
        kmlock.lock();
        try {
            this.km = 101;
            kmcond.signal();
        } finally {
            kmlock.unlock();
        }
    }

    //     变化地点 然后通知处于wait状态并需要处理地点的线程进行业务处理
    public void changeSite() {
        sitelock.lock();
        try {
            this.site = "北京";
            sitecond.signal();
        } finally {
            sitelock.unlock();
        }
    }

    public void waitKm() {
        kmlock.lock();
        try {
            while (this.km <= 100) {
                try {
                    kmcond.await();
                    System.out.println("我是里程 当前线程" + Thread.currentThread().getName() + " is be notify");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        } finally {
            kmlock.unlock();
        }

    }

    public void waitSite() {
        sitelock.lock();
        try {
            while (CITY.equals(this.site)) {
                try {
                   sitecond.await();
                    System.out.println("我是地址  当前线程" + Thread.currentThread().getName() + " is be notify");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
            System.out.println("我是地址  " + Thread.currentThread().getName() + " 货已经送到 site = " + this.site);
        } finally {
            sitelock.unlock();
        }

    }

}

  1. 了解LockSupper
    作用: 1. 阻塞一个线程
    2. 唤醒一个线程
    3. 构建同步组件的基础工具
    park开头的方法 进行阻塞
    unpark 方法 唤醒
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值