Lock and Condition 实现线程同步

lock 和 synchronized 相似  可以替代这个关键字

Lock lock=new ReentrantLock()

lock.lock(); 进入共享代码区

try{

code......

}finnaly{

lock.unlock()

}

lock.unlock()解开锁

基本和synchronize是一样的,原来的synchronized是锁对象,这个lock相当于有了单独的对象

为了避免贡献代码部分发生异常导致 无法释放锁,所以加了一个try catch finnaly来保证每次锁都能够释放


注意,synchronized是用来控制实现原子性的,必须等这部分代码执行完,其他线程才能使用这部分代码


读写锁分为读锁和写锁,读锁和读锁不互斥,读锁和写锁互斥,写锁和写锁互斥 


有点模糊 解释一下,这个类 里面有一个共享数据data,同时有一个度方法和一个写方法,在读方法前面加上读锁,在写方法前面加上写锁,这样就可以看到多个线程同时读 但是只有一个线程在执行写方法,我们在这里不能用lock的原因是,lock一旦锁上之后,没有办法进行多个线程的读操作,这样读操作也变为互斥操作了,所以我们使用读写锁来控制这种读写操作。

 condition 主要用于线程通信,功能和wait notify一样,condition.await  condition.signal  可以实现多路等待

阻塞队列,主要是用来实现一个队列,在空的时候可以阻塞取数据,在满的时候后可以阻塞放数据


private final Condition notFull;
private final Condition notEmpty;

public ArrayBlockingQueue(int capacity, boolean fair) {
        //省略其他代码
        notEmpty = lock.newCondition();
        notFull =  lock.newCondition();
    }

public void put(E e) throws InterruptedException {
        checkNotNull(e);
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            while (count == items.length)
                notFull.await();
            insert(e);
        } finally {
            lock.unlock();
        }
}

public E take() throws InterruptedException {
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            while (count == 0)
                notEmpty.await();
            return extract();
  } finally {
            lock.unlock();
        }
}

private void insert(E x) {
        items[putIndex] = x;
        putIndex = inc(putIndex);
        ++count;
        notEmpty.signal();
    }


信号灯技术 semaphore



Semaphore维护了当前访问的个数,提供同步机制,控制同时访问的个数。在数据结构中链表可以保存“无限”的节点,用Semaphore可以实现有限大小的链表。另外重入锁 ReentrantLock 也可以实现该功能,但实现上要复杂些。 

下面的Demo中申明了一个只有5个许可的Semaphore,而有20个线程要访问这个资源,通过acquire()和release()获取和释放访问许可。

package com.test;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Semaphore;

public class TestSemaphore {

                public static void main(String[] args) {

                // 线程池

                ExecutorService exec = Executors.newCachedThreadPool();

                // 只能5个线程同时访问

                final Semaphore semp = new Semaphore(5);

                 // 模拟20个客户端访问

                 for (int index = 0; index < 20; index++) {

                              final int NO = index;

                              Runnable run = new Runnable() {

                                                 public void run() {

                                                            try {

                                                                    // 获取许可

                                                                    semp.acquire();

                                                                    System.out.println("Accessing: " + NO);

                                                                    Thread.sleep((long) (Math.random() * 10000));

                                                                    // 访问完后,释放

                                                                    semp.release();

                                                                    System.out.println("-----------------"+semp.availablePermits());

                                                            } catch (InterruptedException e) {

                                                                    e.printStackTrace();

                                                            }

                                                  }

                                      };

                      exec.execute(run);

             }

             // 退出线程池

             exec.shutdown();

       }

执行结果如下:

Accessing: 0

Accessing: 1

Accessing: 3

Accessing: 4

Accessing: 2

-----------------0

Accessing: 6

-----------------1

Accessing: 7

-----------------1

Accessing: 8

-----------------1

Accessing: 10

-----------------1

Accessing: 9

-----------------1

Accessing: 5

-----------------1

Accessing: 12

-----------------1

Accessing: 11

-----------------1

Accessing: 13

-----------------1

Accessing: 14

-----------------1

Accessing: 15

-----------------1

Accessing: 16

-----------------1

Accessing: 17

-----------------1

Accessing: 18

-----------------1

Accessing: 19

CyclicBarrier 主要是用来控制线程都同时到达之后再往后走 类似与一个约定 所有的线程都到达路障地点之后才开始往下走



cuuntdownlaunch  是一个计数器,通过调用countDown 做减一操作,通过wait 等待这个计数器减为0


exchange 用户交换数据,两者到达同一个时间地点后 拿着数据,这个时候就开始交换数据




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值