美文网首页
2.concurrent

2.concurrent

作者: _少年不知愁 | 来源:发表于2018-08-20 17:17 被阅读0次

1.Lock 锁
synchronized修饰跟lock效果一样

   Lock lock = new ReentrantLock();
        new Thread(new Runnable() {
            @Override
            public void run() {
                lock.lock();
                try {
                    System.out.println("Thread++++等待中");

                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }).start();

        lock.lock();
        System.out.println("等待中");
        Thread.sleep(3000);
        lock.unlock();
        System.out.println("ending+++++++++===");

2.读写锁
分读锁和写锁 多个读锁不互斥,对锁与血锁互斥,写锁与写锁互斥
下面是ReentrantReadWriteLock注释中的demo实现一个简单的缓存机制


    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            System.out.println(processCachedData());
        }
    }

    private static Object data;
    private static volatile boolean cacheValid;
    private final static ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

    public static Object processCachedData() {
        rwl.readLock().lock();
        if (!cacheValid) {
            // Must release read lock before acquiring write lock
            rwl.readLock().unlock();
            rwl.writeLock().lock();
            try {
                // Recheck state because another thread might have
                // acquired write lock and changed state before we did.
                if (!cacheValid) {
                    data = System.currentTimeMillis();
                    cacheValid = true;
                }
                // Downgrade by acquiring read lock before releasing write lock
                rwl.readLock().lock();
            } finally {
                rwl.writeLock().unlock(); // Unlock write, still hold read
            }
        }

        try {
            return data;
        } finally {
            rwl.readLock().unlock();
        }
    }

3.Condition

    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();
    condition.await();相当于this.wait() 
    condition.signal();相当于 this.notify()

4.Semaphore
只允许3个线程同时执行

{
        ExecutorService executorService = Executors.newCachedThreadPool();
        Semaphore s = new Semaphore(3);
        for (int i = 0; i < 10; i++) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    try {
                        s.acquire();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "::进入,当前使用线程为:" + (3 - s.availablePermits()));
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    s.release();
                    System.out.println(Thread.currentThread().getName() + "::离开,当前使用线程为:" + (3 - s.availablePermits()));

                }
            };

            executorService.execute(runnable);
        }
    }

结果:

pool-1-thread-2::进入,当前使用线程为:3
pool-1-thread-3::进入,当前使用线程为:3
pool-1-thread-1::进入,当前使用线程为:3
pool-1-thread-2::离开,当前使用线程为:0
pool-1-thread-3::离开,当前使用线程为:0
pool-1-thread-6::进入,当前使用线程为:2
pool-1-thread-4::进入,当前使用线程为:1
pool-1-thread-1::离开,当前使用线程为:0
pool-1-thread-5::进入,当前使用线程为:3
pool-1-thread-8::进入,当前使用线程为:2
pool-1-thread-4::离开,当前使用线程为:2
pool-1-thread-7::进入,当前使用线程为:3
pool-1-thread-6::离开,当前使用线程为:2
pool-1-thread-9::进入,当前使用线程为:2
pool-1-thread-5::离开,当前使用线程为:2
pool-1-thread-7::离开,当前使用线程为:2
pool-1-thread-8::离开,当前使用线程为:1
pool-1-thread-9::离开,当前使用线程为:1
pool-1-thread-10::进入,当前使用线程为:1
pool-1-thread-10::离开,当前使用线程为:0

5.CyclicBarrier
cb.await();等待控制访问线程数,当等待数为3时,继续往下走

{
        ExecutorService service = Executors.newCachedThreadPool();
        final CyclicBarrier cb = new CyclicBarrier(3);
        for (int i = 0; i < 3; i++) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep((long) (Math.random() * 10000));
                        System.out.println("线程" + Thread.currentThread().getName() + ":" + cb.getNumberWaiting());
                        cb.await();
                        System.out.println("全到");

                        Thread.sleep((long) (Math.random() * 10000));
                        System.out.println("线程" + Thread.currentThread().getName() + ":" + cb.getNumberWaiting());

                        cb.await();
                        System.out.println("全到");

                        Thread.sleep((long) (Math.random() * 10000));
                        System.out.println("线程" + Thread.currentThread().getName() + ":" + cb.getNumberWaiting());
                        cb.await();
                        System.out.println("全到");

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
            service.execute(runnable);
        }
    }

输出结果:

线程pool-1-thread-1:0
线程pool-1-thread-3:1
线程pool-1-thread-2:2
线程pool-1-thread-2:0
线程pool-1-thread-1:1
线程pool-1-thread-3:2
线程pool-1-thread-1:0
线程pool-1-thread-3:1
线程pool-1-thread-2:2

6.CountDownLatch
当设置计数为1时,可使用countDown可以指定唤醒 那个对应线程
demo 实现a线程执行完,在执行b线程,b线程执行完 在执行c线程 依次往复50次

public class CountdownLatchTest {

    /**
     * new一个新对象将设置数值 计数器为0时,则所有等待或单个等待开始执行
     *
     * @param args
     */
    public static void main(String[] args) {
//        CountDownLatch cd1 = new CountDownLatch(1);
//        CountDownLatch cd2 = new CountDownLatch(1);
//        CountDownLatch cd3 = new CountDownLatch(1);
        Test2 test2 = new Test2();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    test2.sub1(i);
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    test2.sub2(i);
                }
            }
        }).start();

        for (int i = 0; i < 20; i++) {
            test2.sub3(i);
        }

    }
}

7.Exchanger
实现线程之间的数据互换,如果当一个线程正在交换,无交换对象 则等待下一个线程 完成交换

{
        Exchanger e = new Exchanger();
        new Thread(new Runnable() {
            @Override
            public void run() {
                String t1 = "线程1";
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                try {
                    String b = (String) e.exchange(t1);
                    System.out.println("线程1交换结果:" + b);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
            }
        }).start();
        String t2 = "线程2";
        String b1 = (String) e.exchange(t2);
        System.out.println("线程2交换结果:" + b1);

    }

输出结果:
等待5s后 输出结果

线程1交换结果:线程2
线程2交换结果:线程1

相关文章

  • 2.concurrent

    1.Lock 锁synchronized修饰跟lock效果一样 2.读写锁分读锁和写锁 多个读锁不互斥,对锁与血锁...

网友评论

      本文标题:2.concurrent

      本文链接:https://www.haomeiwen.com/subject/wqjliftx.html