java的干儿子锁Lock

时间:2020-07-16 11:46:11   收藏:0   阅读:56

大数据时代随之而来的就是并发问题。Java开发本身提供了关于锁的操作。我们知道的有Synchronized。 这个是JVM层面的锁。操作简单

Lock的由来

线程之间的交互

- await/wait sleep yield
释放锁 释放 不释放 不释放
就绪节点 notify/notifyall方法后 休眠时间后 立刻就绪
提供者 Object/Condition Thread Thread
代码位置 代码块 任意 任意
Object.notify Object.notifyall Condition.signal
随机唤醒挂载线程之一 随机唤醒挂载线程之一 按顺序唤醒当前condition上的挂载线程

Lock方法简介

技术图片

lock()

lockInterruptibly()

trylock()

trylock(long,TimeUnit)

unlock()

newCondition()

使用

技术图片

Lock保障高并发

源码位置


package com.github.zxhtom.lock;

import lombok.Data;

import java.util.concurrent.locks.Lock;

/**
 * @author 张新华
 * @version V1.0
 * @Package com.github.zxhtom.lock
 * @date 2020年07月09日, 0009 14:30
 * @Copyright ? 2020 安元科技有限公司
 */
public class Counter {
    private static Counter util = new Counter();
    public static Counter getInstance(){
        return util;
    }
    private  int index;
    public static Counter getUtil() {
        return util;
    }
    public static void setUtil(Counter util) {
        Counter.util = util;
    }
    public int getIndex() {
        return index;
    }
    public void setIndex(Lock lock , int index) {
        /*这里加锁解锁是为了显示可重入性,在外部为加锁解锁*/
        lock.lock();
        this.index = index;
        lock.unlock();
    }
}



package com.github.zxhtom.lock;

import java.util.Random;
import java.util.concurrent.locks.Lock;

/**
 * @author 张新华
 * @version V1.0
 * @Package com.github.zxhtom.lock
 * @date 2020年07月09日, 0009 14:19
 * @Copyright ? 2020 安元科技有限公司
 */
public class LockRunnable implements Runnable {
    private Lock lock;
    public LockRunnable(Lock lock ) {
        this.lock = lock;
    }

    @Override
    public void run() {
        try {
            Thread.sleep(new Random().nextInt(10));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        /*lock、unlock之间的业务就能保证同一时刻只有一个线程访问。前提* 是同一个lock对象 , setIndex中也有lock 程序正常运行说明可重* 入
        */
        this.lock.lock();
        Counter instance = Counter.getInstance();
        instance.setIndex(this.lock,instance.getIndex()+1);
        this.lock.unlock();
    }
}



package com.github.zxhtom.lock;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author 张新华
 * @version V1.0
 * @Package com.github.zxhtom.lock
 * @date 2020年07月01日, 0001 14:24
 * @Copyright ? 2020 安元科技有限公司
 */
public class ReentrantLockDemo {
    public static void main(String[] args) {
        ReentrantLock lock = new ReentrantLock();
        List<Thread> threadList = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            int finalI = i;
            Thread thread = new Thread(new LockRunnable(lock));
            thread.start();
            threadList.add(thread);
        }
        for (Thread thread : threadList) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(Counter.getInstance().getIndex());
    }
}


Lock期间线程挂起

场景: 1000个线程按名字的奇偶性分组,奇数一组、偶数一组。奇数执行完之后需要将锁传递给同组的线程 。

技术图片

LockRunnable改造

技术图片


package com.github.zxhtom.lock;

import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/**
 * @author 张新华
 * @version V1.0
 * @Package com.github.zxhtom.lock
 * @date 2020年07月09日, 0009 14:19
 * @Copyright ? 2020 安元科技有限公司
 */
public class LockRunnable implements Runnable {
    private Lock lock;
    private Condition condition;
    private int index;
    public LockRunnable(Lock lock , Condition condition,int index) {
        this.lock = lock;
        this.condition = condition;
        this.index = index;
    }

    @Override
    public void run() {
        try {
            this.lock.lock();
            //if (index != 0) {
                condition.await();
            //}
            System.out.println(Thread.currentThread().getName());
            Counter instance = Counter.getInstance();
            instance.setIndex(this.lock,instance.getIndex()+1);
            condition.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            this.lock.unlock();
        }
    }
}


ReentrantLockDemo改造

技术图片


package com.github.zxhtom.lock;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author 张新华
 * @version V1.0
 * @Package com.github.zxhtom.lock
 * @date 2020年07月01日, 0001 14:24
 * @Copyright ? 2020 安元科技有限公司
 */
public class ReentrantLockDemo {
    public static void main(String[] args) {
        ReentrantLock lock = new ReentrantLock();
        /*奇数*/
        Condition oddCondition = lock.newCondition();
        /*偶数*/
        Condition evenCondition = lock.newCondition();
        List<Thread> threadList = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            int finalI = i;
            Condition condition = null;
            if (i % 2 == 0) {
                condition = evenCondition;
            } else {
                condition = oddCondition;
            }
            Thread thread = new Thread(new LockRunnable(lock,condition,i));
            thread.start();
            threadList.add(thread);
        }
        try {
            lock.lock();
            oddCondition.signal();
        }finally {
            lock.unlock();
        }
        try {
            /*休眠足够长,目的是不与前面队列抢锁.可以调更长时间。
            * 这样测试准确*/
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        try {
            lock.lock();
            evenCondition.signal();
        }finally {
            lock.unlock();
        }
        for (Thread thread : threadList) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        System.out.println(Counter.getInstance().getIndex());
    }
}


总结

加入战队

# 加入战队

微信公众号

技术图片

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!