jdk锁的使用

ReentrantLock
public class JdkLockTest implements Runnable{

    private ReentrantLock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    private static int i = 0;

    public static void main(String[] args) {
        JdkLockTest jdkLockTest = new JdkLockTest();
        Thread t1 = new Thread(jdkLockTest);
        Thread t2 = new Thread(jdkLockTest);
        Thread t3 = new Thread(jdkLockTest);
        t1.start();
        t2.start();
        t3.start();
    }

    @Override
    public void run(){
        lock .lock();

        try {
            System.out.println("开始等待2s");
            condition.await(2, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("ThreadName=" + Thread.currentThread().getName());
        for(int j=0; j<1000000; j++){
            i++;
        }
        System.out.println("i = " + i);
        lock.unlock();
    }
}

ReentrantLock其他方法

  • getHoldCount() 查询当前线程保持此锁的次数,也就是执行此线程执行lock方法的次数
  • getQueueLength()返回正等待获取此锁的线程估计数,比如启动10个线程,1个线程获得锁,此时返回的是9
  • getWaitQueueLength(Condition condition)返回等待与此锁相关的给定条件的线程估计数。比如10个线程,用同一个condition对象,并且此时这10个线程都执行了condition对象的await方法,那么此时执行此方法返回10
  • hasWaiters(Condition condition)查询是否有线程等待与此锁有关的给定条件(condition),对于指定contidion对象,有多少线程执行了condition.await方法
  • hasQueuedThread(Thread thread)查询给定线程是否等待获取此锁
  • hasQueuedThreads()是否有线程等待此锁
  • isFair()该锁是否公平锁
  • isHeldByCurrentThread() 当前线程是否保持锁锁定,线程的执行lock方法的前后分别是false和true
  • isLock()此锁是否有任意线程占用
  • lockInterruptibly()如果当前线程未被中断,获取锁
  • tryLock()尝试获得锁,仅在调用时锁未被线程占用,获得锁
  • tryLock(long timeout TimeUnit unit)如果锁在给定等待时间内没有被另一个线程保持,则获取该锁

 

 

Semaphore 
public class SemaphoreTest {

    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(3);
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        for(int i=0; i<10; i++){
            executorService.execute(new Test(semaphore));
        }
        executorService.shutdown();
    }


}

class Test implements Runnable{

    private Semaphore semaphore;
    private int i=0;

    public Test(){}
    public Test(Semaphore semaphore){
        this.semaphore = semaphore;
    }

    @Override
    public void run() {
        try {
            semaphore.acquire();
            for(int j=0; j<1000000; j++){
                i++;
            }
            System.out.println("i = " + i);
            System.out.println("当前线程=====》"+ Thread.currentThread().getName());
            semaphore.release();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

其他方法,(摘自网络)

Semaphore的方法如下:

——Semaphore(permits)  初始化许可证数量的构造函数

——Semaphore(permits,fair)  初始化许可证数量和是否公平模式的构造函数

——isFair()  是否公平模式FIFO

——availablePermits()  获取当前可用的许可证数量

——acquire()

当前线程尝试去阻塞的获取1个许可证。

此过程是阻塞的,它会一直等待许可证,直到发生以下任意一件事:

当前线程获取了1个可用的许可证,则会停止等待,继续执行。
当前线程被中断,则会抛出InterruptedException异常,并停止等待,继续执行。
——acquire(permits)

当前线程尝试去阻塞的获取permits个许可证。

此过程是阻塞的,它会一直等待许可证,直到发生以下任意一件事:

当前线程获取了n个可用的许可证,则会停止等待,继续执行。
当前线程被中断,则会抛出InterruptedException异常,并停止等待,继续执行。

——acquierUninterruptibly()

当前线程尝试去阻塞的获取1个许可证(不可中断的)。

此过程是阻塞的,它会一直等待许可证,直到发生以下任意一件事:

当前线程获取了1个可用的许可证,则会停止等待,继续执行。
——acquireUninterruptibly(permits)

当前线程尝试去阻塞的获取permits个许可证。

此过程是阻塞的,它会一直等待许可证,直到发生以下任意一件事:

当前线程获取了n个可用的许可证,则会停止等待,继续执行。
——tryAcquire()

当前线程尝试去获取1个许可证。

此过程是非阻塞的,它只是在方法调用时进行一次尝试。

如果当前线程获取了1个可用的许可证,则会停止等待,继续执行,并返回true。

如果当前线程没有获得这个许可证,也会停止等待,继续执行,并返回false。

——tryAcquire(permits)

当前线程尝试去获取permits个许可证。

此过程是非阻塞的,它只是在方法调用时进行一次尝试。

如果当前线程获取了permits个可用的许可证,则会停止等待,继续执行,并返回true。

如果当前线程没有获得permits个许可证,也会停止等待,继续执行,并返回false。

——tryAcquire(timeout,TimeUnit)

当前线程在限定时间内,阻塞的尝试去获取1个许可证。

此过程是阻塞的,它会一直等待许可证,直到发生以下任意一件事:

当前线程获取了可用的许可证,则会停止等待,继续执行,并返回true。
当前线程等待时间timeout超时,则会停止等待,继续执行,并返回false。
当前线程在timeout时间内被中断,则会抛出InterruptedException一次,并停止等待,继续执行。
——tryAcquire(permits,timeout,TimeUnit)

当前线程在限定时间内,阻塞的尝试去获取permits个许可证。

此过程是阻塞的,它会一直等待许可证,直到发生以下任意一件事:

当前线程获取了可用的permits个许可证,则会停止等待,继续执行,并返回true。
当前线程等待时间timeout超时,则会停止等待,继续执行,并返回false。
当前线程在timeout时间内被中断,则会抛出InterruptedException一次,并停止等待,继续执行。
——release() 当前线程释放1个可用的许可证。

——release(permits) 当前线程释放permits个可用的许可证。

——drainPermits() 当前线程获得剩余的所有可用许可证。

——hasQueuedThreads() 判断当前Semaphore对象上是否存在正在等待许可证的线程。

——getQueueLength() 获取当前Semaphore对象上是正在等待许可证的线程数量。

 

ReadWriteLock   当写操作时,其他线程无法读取或写入数据,而当读操作时,其它线程无法写入数据,但却可以读取数据 。

public class ReadWriteLockTest {

    public static void main(String[] args) {
        TestReadWrite testReadWrite = new TestReadWrite();

        for(int i=0; i<10; i++){
            new Thread(testReadWrite::read).start();
        }

        for(int j=0; j<10; j++) {
            new Thread(() -> testReadWrite.write("你好")).start();
        }
    }

}

class TestReadWrite{
    private String data;
    private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    public void read(){
        readWriteLock.readLock().lock();//线程只能读,不能写
        System.out.println(Thread.currentThread().getName() + "读取数据========");
        try {
            Thread.sleep((long)(Math.random()*1000));
            System.out.println(Thread.currentThread().getName() + "读取完数据 :" + data);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            readWriteLock.readLock().unlock();
        }
    }

    public void write(String data){
        readWriteLock.writeLock().lock();//不允许其他线程读写操作
        System.out.println(Thread.currentThread().getName() + "写数据========");
        try {
            Thread.sleep((long) (Math.random() * 1000));
            this.data = data;
            System.out.println(Thread.currentThread().getName() + "写数据完成 ==" + data);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            readWriteLock.writeLock().unlock();
        }

    }
}
CountDownLacth

某一线程在开始运行前等待n个线程执行完毕。将CountDownLatch的计数器初始化为n new CountDownLatch(n) ,每当一个任务线程执行完毕,就将计数器减1 countdownlatch.countDown(),当计数器的值变为0时,在CountDownLatch上 await() 的线程就会被唤醒。

public class CountDownLacthTest {

    public static void main(String[] args) {
        final CountDownLatch countDown = new CountDownLatch(2);

        Thread t1 = new Thread(() -> {
            System.out.println("线程t1开始执行-------------");
            try {
                System.out.println("线程t1等待其他线程-------------");
                countDown.await();
                System.out.println("线程t1继续执行-------------");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"t1");

        Thread t2 = new Thread(() -> {
            try {
                System.out.println("线程t2开始执行-------------");
                Thread.sleep((long) (Math.random()*1000));
                System.out.println("线程t2执行完毕-------------");
                countDown.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"t2");

        Thread t3 = new Thread(() -> {
            try {
                System.out.println("线程t3开始执行-------------");
                Thread.sleep((long) (Math.random()*1000));
                System.out.println("线程t3执行完毕-------------");
                countDown.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"t3");

        t1.start();
        t2.start();
        t3.start();

    }
}

CyclicBarrier   注意:当线程数和parties不一致的时候有可能发生阻塞问题!最后剩下的线程数不足parties,无法继续执行下去

public class CyclicBarrierTest {
    public static void main(String[] args) {
        ExecutorService service = Executors.newCachedThreadPool();
        final CyclicBarrier cb = new CyclicBarrier(3);//当有3个线程到达时,共同执行
//final CyclicBarrier cb = new CyclicBarrier(3, () -> System.out.println("********我最先执行***********"));
        for (int i = 0; i < 3; i++) {
            Runnable runnable = () -> {
                try {
                    Thread.sleep((long) (Math.random() * 1000));
                    System.out.println("线程" + Thread.currentThread().getName() +
                            "即将到达集合地点1,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
                    cb.await();//到此如果没有达到公共屏障点,则该线程处于等待状态,如果达到公共屏障点则所有处于等待的线程都继续往下运行

                    Thread.sleep((long) (Math.random() * 1000));
                    System.out.println("线程" + Thread.currentThread().getName() +
                            "即将到达集合地点2,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
                    cb.await();
                    Thread.sleep((long) (Math.random() * 1000));
                    System.out.println("线程" + Thread.currentThread().getName() +
                            "即将到达集合地点3,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");
                    cb.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            };
            service.execute(runnable);
        }
        service.shutdown();
    }
}

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值