线程: ReentrantLock类

使用ReentrantLock实现同步

  ReentrantLock对象的lock()方法获取锁, 调用unlock()方法释放锁

  调用ReentrantLock对象的lock()方法的线程就持有"对象监视器",其他线程只有等待锁被释放时再次争抢。效果和使用synchronized关键字一样。

   关键字synchronized与wait()和notify()/notifyAll()方法相结合可以实现等待/通知模式, 类ReentrantLock也可以实现同样的功能,但需要借助于Condition对象。Condition类是再jdk5中出现的技术,使用它有更好的灵活性,比如可以实现多路通知功能。使用ReentrantLock结合Condition类是可以实现"选择性通知",这个功能非常重要。

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class MySservice {
    private ReentrantLock lock = new ReentrantLock();
    private Condition conditionA = lock.newCondition();
    private Condition conditionB = lock.newCondition();
    private boolean hasValue = false;

    public void set(){
        try {
            lock.lock();
            while(hasValue == true){
                System.out.println("setsetsetset"+Thread.currentThread().getName());
                conditionA.await();
            }
            System.out.println("set");
            hasValue = true;
            conditionB.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public void get(){
        try {
            lock.lock();
            while(hasValue == false){
                System.out.println("getgetgetget");
                conditionB.await();
            }
            System.out.println("get");
            hasValue = false;
            conditionA.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
}


public class MyThreadA extends Thread {

    private MySservice mySservice;
    public MyThreadA(MySservice mySservice){
        super();
        this.mySservice = mySservice;
    }

    @Override
    public void run(){
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            mySservice.set();
        }
    }
}

public class MyThreadB extends Thread {

    private MySservice mySservice;
    public MyThreadB(MySservice mySservice){
        super();
        this.mySservice = mySservice;
    }

    @Override
    public void run(){
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            mySservice.get();
        }
    }
}



public class Run {
    public static void main(String[] args) {
        MySservice mySservice = new MySservice();

        MyThreadA[] myThreadA = new MyThreadA[10];
        MyThreadB[] myThreadB = new MyThreadB[10];

        for (int i = 0; i < 10; i++) {
            myThreadA[i] = new MyThreadA(mySservice);
            myThreadB[i] = new MyThreadB(mySservice);
            myThreadA[i].setName((i+1)+"");
            myThreadA[i].start();
            myThreadB[i].start();
        }
    }
}

方法getHoldCount()

  该方法是查询当前线程保持此锁定的个数,也就是调用lock()方法的次数

import java.util.concurrent.locks.ReentrantLock;

public class Service {
    private ReentrantLock lock = new ReentrantLock();

    public void serviceMethod1(){
        try{
            lock.lock();
            System.out.println("serviceMethod1 getHoldCount="
                +lock.getHoldCount());

            serviceMethod2();
        }finally {
            lock.unlock();
        }
    }

    public void serviceMethod2(){
        try{
            lock.lock();
            System.out.println("serviceMethod2 getHoldCount="
                    +lock.getHoldCount());

        }finally {
            lock.unlock();
        }
    }
}


public class Run {
    public static void main(String[] args) {
        Service service = new Service();
        service.serviceMethod1();
    }
}

 方法getQueueLength()

  返回正等待获取此锁定的线程估计数。

public class Run {
    public static void main(String[] args) throws InterruptedException {
        final Service service = new Service();

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                service.serviceMethod1();
            }
        };

        Thread[] threadArray = new Thread[10];

        for (int i = 0; i < 10; i++) {
            threadArray[i] = new Thread(runnable);
        }

        for (int i = 0; i < 10; i++) {
            threadArray[i].start();
        }

        Thread.sleep(2000);
        System.out.println("有线程树:"+service.lock.getQueueLength()+"正在等待锁!");
    }
}


import java.util.concurrent.locks.ReentrantLock;

public class Service {
    public ReentrantLock lock = new ReentrantLock();

    public void serviceMethod1(){
        try{
            lock.lock();
            System.out.println("ThreadName="+Thread.currentThread().getName()+" 进入方法!");
            Thread.sleep(1000);
        }catch(InterruptedException ex){
            ex.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
}

方法hasQueuedThread(), hasQueuedThreads()

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class Service {
    public ReentrantLock lock = new ReentrantLock();

    public Condition newCondition = lock.newCondition();

    public void waitMethod(){
        try{
            lock.lock();
            Thread.sleep(Integer.MAX_VALUE);
        }catch (InterruptedException ex){
            ex.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
}

public class Run {
    public static void main(String[] args) throws InterruptedException {
        final Service service = new Service();
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                service.waitMethod();
            }
        };

        Thread threadA = new Thread(runnable);
        threadA.start();
        Thread.sleep(500);
        Thread threadB = new Thread(runnable);
        threadB.start();
        Thread.sleep(500);
        System.out.println(service.lock.hasQueuedThread(threadA));
        System.out.println(service.lock.hasQueuedThread(threadB));
        System.out.println(service.lock.hasQueuedThreads());
        System.out.println(service.lock.getQueueLength());
    }
}

方法isFair()

     判断是不是公平锁

import java.util.concurrent.locks.ReentrantLock;

public class Service {

    private ReentrantLock lock;

    public Service(boolean isFair){
        super();
        lock = new ReentrantLock(isFair);
    }

    public void serviceMethod(){
        try{
            lock.lock();
            System.out.println(Thread.currentThread().getName()+" 公平锁情况:"+lock.isFair());
        }finally {
            lock.unlock();
        }
    }
}


public class Run {
    public static void main(String[] args) {
        Service service1 = new Service(true);
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                service1.serviceMethod();
            }
        };

        Thread t1 = new Thread(runnable,"A");
        t1.start();

        Service service2 = new Service(false);
        Runnable runnable2 = new Runnable() {
            @Override
            public void run() {
                service2.serviceMethod();
            }
        };

        Thread t2 = new Thread(runnable2,"B");
        t2.start();
    }
}

方法isHeldByCurrentThread()

  查询当前线程是否保持此锁定

import java.util.concurrent.locks.ReentrantLock;

public class Service {
    private ReentrantLock lock;

    public Service(){
        super();
        lock = new ReentrantLock();
    }

    public void serviceMethod(){
        try{
            System.out.println("当前线程是否保持此锁定"+lock.isHeldByCurrentThread());
            lock.lock();
            System.out.println("当前线程是否保持此锁定"+lock.isHeldByCurrentThread());
        }finally {
            lock.unlock();
        }
    }
}


public class Run {
    public static void main(String[] args) {
        final Service service1 = new Service();
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                service1.serviceMethod();
            }
        };

        Thread t = new Thread(runnable);
        t.start();
    }
}

方法tryLock(long timeout, TimeUnit unit)

     如果锁定在给定等待时间内没有被另一个线程保持,且当前线程未被中断,则获取该锁定

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

public class MyService {
    private ReentrantLock lock = new ReentrantLock();
    public void waitMethod(){
        try{
            if(lock.tryLock(3, TimeUnit.SECONDS)){
                System.out.println("    "+Thread.currentThread().getName()
                    +"获得锁的时间:"+System.currentTimeMillis());
                Thread.sleep(10000);
            }else{
                System.out.println("    "+Thread.currentThread().getName()
                        +"没有获得锁");
            }
        }catch (InterruptedException ex){
            ex.printStackTrace();
        }finally {
            if(lock.isHeldByCurrentThread()){
                lock.unlock();
            }
        }
    }
}


public class Run {
    public static void main(String[] args) {
        final MyService service = new MyService();
        Runnable runnableRef = new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()
                    +" 调用waitMethod时间: "+System.currentTimeMillis());
                service.waitMethod();
            }
        };

        Thread threadA = new Thread(runnableRef);
        threadA.setName("A");
        threadA.start();

        Thread threadB = new Thread(runnableRef);
        threadB.setName("B");
        threadB.start();
    }
}

  

发布了557 篇原创文章 · 获赞 40 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/m0_37564426/article/details/103438205
今日推荐