ReentrantLock + ThreadLocal

ReentrantLock

Synchronized锁

例:

synchronized void m1(){
        for (int i = 0; i < 10; i++) {

            try {
                TimeUnit.SECONDS.sleep(1);//睡1秒
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            System.out.println(i);

        }
    }

    synchronized void m2(){

        System.out.println("m2......");
    }

    public static void main(String[] args) {

        ReentrantLock1 r1 = new ReentrantLock1();
        new Thread(r1 :: m1).start();//开启线程

        try {
            TimeUnit.SECONDS.sleep(1);
        }catch (InterruptedException e){
            e.printStackTrace();
        }

        new Thread(r1 :: m2).start();

    }

上面的例程是使用Synchronized锁,下面将它改写为ReentrantLock

Lock lock = new ReentrantLock();

    void m1(){
        try {
            lock.lock();//相当于synchronized(this)
            for (int i = 0; i < 10; i++) {
                TimeUnit.SECONDS.sleep(1);
                System.out.println(i);
            }
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    void m2(){
        lock.lock();
        System.out.println("m2.....");
        lock.unlock();
    }


    public static void main(String[] args) {

        ReentrantLock2 r2 = new ReentrantLock2();
        new Thread(r2 :: m1).start();
        try {
            TimeUnit.SECONDS.sleep(1);

        }catch (InterruptedException e){
            e.printStackTrace();
        }

        new Thread(r2 :: m2).start();
    }

对比之后发现,ReentrantLock比Synchronized锁多了手动释放的过程

tryLock

tryLock返回一个boolean类型的值,当前线程尝试是否能够得到锁,能够得到返回true,不能得到返回false

 Lock lock = new ReentrantLock();

    void m1(){

        lock.lock();

        try {
            for (int i = 0; i < 100; i++) {
                TimeUnit.SECONDS.sleep(1);
                System.out.println(i);
            }
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }


    void m2(){

        boolean locked = false;

        try {
            locked = lock.tryLock(5,TimeUnit.SECONDS);//尝试看是否能够得到锁(5秒)
            System.out.println(locked ? "拿到锁" : "没有拿到锁");
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            if (locked) lock.unlock();
        }

    }


    public static void main(String[] args) {

        ReentrantLock3 r3 = new ReentrantLock3();

        new Thread(r3 :: m1).start();

        try {
            TimeUnit.SECONDS.sleep(1);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        new Thread(r3 :: m2).start();

    }

lockInterruptibly

当前线程等待其他线程使用完锁,如果其他线程一直在使用锁,会造成程序一直卡住,此时使用lockInterruptibly进行打断

public static void main(String[] args) {


    Lock lock = new ReentrantLock();

    Thread t1 = new Thread(() ->{

        try {

            lock.lock();
            System.out.println("t1 start");
            TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
            System.out.println("t1 end");

        }catch (InterruptedException e){
            System.out.println("interrupted!");
        }finally {
            lock.unlock();
        }

    });
    t1.start();

    Thread t2 = new Thread(() ->{

        try {
//            lock.lock();
            lock.lockInterruptibly();   //可以对interrupt()方法做出响应
            System.out.println("t2 start");
            TimeUnit.SECONDS.sleep(5);
            System.out.println("t2 end");
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            if(((ReentrantLock) lock).isHeldByCurrentThread()) lock.unlock();
        }

    });
    t2.start();


    try {
        TimeUnit.SECONDS.sleep(1);
    }catch (InterruptedException e){
        e.printStackTrace();
    }

    t2.interrupt(); //打断线程2的等待

    }

设置公平锁

ReentrantLock支持设置公平锁

private static ReentrantLock lock = new ReentrantLock(true);//设置公平锁

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + "获得锁");
            }finally {
                lock.unlock();
            }
        }
    }


    public static void main(String[] args) {

        ReentrantLock5 r5 = new ReentrantLock5();

        Thread th1 = new Thread(r5);
        Thread th2 = new Thread(r5);
        th1.start();
        th2.start();

    }

生产者消费者

使用wait和notify实现

public class MyContainer<T>{
    
    final private LinkedList<T> lists = new LinkedList<>();
    final private int MAX = 10;//最多10个元素
    private int count = 0;
    
    
    public synchronized void put(T t){
        
        while(lists.size() == MAX){ //why while not if?
            
            try{
                this.wait(); //容器满了,让生产者线程等待
            }catch(InterruptedException e){
                e,printStackTrace();
            }
            
        }
        
        lists.add(t);
        ++count;
        this.notifyAll();//唤醒所有消费线程
        
    }
    
    
    public synchronized T get(){
        
        while(lists.size() == 0){
            
            try{
                this.wait(); //容器空了,让所有的消费者线程等待
            }catch(InterruptdException e){
                e.printStackTrace();
            }
            
        }
        
        T first = lists.removeFirst();
        count--;
        this.notifyAll();//通知生产者线程进行生产
        
        return first;
    }
    
    
    
    
    public static void main(String[] args){
        
        MyContainer<String> lists = new MyContainer<>();
        //开启消费者线程
        for(int i = 0;i < 10;i++){
            new Thread(()->{
                for(int j = 0;j < 100;j++)
                    System.out.println(lists.get());
            },"c" + i).start();
        }
        
        try{
            TimeUnit.SECONDS.sleep(2);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        
        //开启生产者线程
        for(int i = 0;i < 2;i++){
            
            new Thread(() -> {
                
                for(int j = 0;j < 25;j++)
                    lists.put(Thread.currentThread().getName() + " " + j);
            },"p" + i).start();
        }
        
        
    }
    
    
}

使用Lock和condition实现

public class Container2<T>{
    
    final private LinkedList<T> lists = new LinkedList<>();
    final private int MAX = 10;
    private int count = 0;
    
    private Lock lock = new ReentrantLock();
    private Condition consumer = lock.newCondition();
    private Condition producer = lock.newCondition();
    
    
    public void put(T t){
        
        try{
            lock.lock();
            while(lists.size() == MAX){
                
                producer.await();
            }
            
            lists.add(t);
            ++count;
            consumer.signalAll
        }catch(InterruptedException e){
            e.printStackTrace();
        }finally{
            lock.unlock();
        }
        
    }
    
    
    
    public T get(){
        
        T first = null;
        
        try{
            
            lock.lock();
            while(lists.size() == 0){
                consumer.await();
            }
             T first = lists.removeFirst();
        	count--;
        	producer.signalAll();
            
        }catch(InterruptedException e){
            e.printStackTrace();
        }finally{
            lock.unlock();
        }
        
       
        return first;
    }
    
    
}

ThreadLocal

可以让每个线程的内容独享,其他线程无法使用

synchronized是时间换空间,等到前面的线程执行完后才能执行。

ThreadLocal是空间换时间,每个对象都是独立的

例程:

public class ThreadLocal1 {

    volatile static Person p = new Person();

    public static void main(String[] args) {

        new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(2);
            }catch (InterruptedException e){
                e.printStackTrace();
            }

            System.out.println(p.name);
        }).start();

        new Thread(() -> {

            try {
                TimeUnit.SECONDS.sleep(1);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            p.name = "lisi";

        }).start();

    }

}


class Person{

    String name = "zhangsan";
}
public class ThreadLocal2 {

    static ThreadLocal<Person> tl = new ThreadLocal<>();

    public static void main(String[] args) {

        new Thread(() -> {

            try {
                TimeUnit.SECONDS.sleep(2);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            System.out.println(tl.get());

        }).start();


        new Thread(() -> {

            try {

                TimeUnit.SECONDS.sleep(1);

            }catch (InterruptedException e){
                e.printStackTrace();
            }
            tl.set(new Person());
        }).start();


    }

    static class Person{
        String name = "zhangsan";
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值