CountDownLatch的用法

在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法。

以下是本文目录大纲:

一.CountDownLatch用法

二.CyclicBarrier用法

三.Semaphore用法

一.CountDownLatch用法

CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能。比如有一个任务A,它要等待其他4个任务执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了

CountDownLatch类只提供了一个构造器:

1
public CountDownLatch(int count) {  };  //参数count为计数值
然后下面这3个方法是CountDownLatch类中最重要的方法:
public void await() throws InterruptedException { };   //调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };  //和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
 

public class Test {
     public static void main(String[] args) {   
         final CountDownLatch latch = new CountDownLatch(2);
 
         new Thread(){
             public void run() {
                 try {
                     System.out.println("子线程"+Thread.currentThread().getName()+"正在执行");
                    Thread.sleep(3000);
                    System.out.println("子线程"+Thread.currentThread().getName()+"执行完毕");
                    latch.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
             };
         }.start();
 
         new Thread(){
             public void run() {
                 try {
                     System.out.println("子线程"+Thread.currentThread().getName()+"正在执行");
                     Thread.sleep(3000);
                     System.out.println("子线程"+Thread.currentThread().getName()+"执行完毕");
                     latch.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
             };
         }.start();
 
         try {
            System.out.println("等待2个子线程执行完毕...");
            latch.await();
            System.out.println("2个子线程已经执行完毕");
            System.out.println("继续执行主线程");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
     }
}


用来验证StringBufffer和StringBuilder的线程安全性
 

package ThreadStudy;

import java.util.concurrent.CountDownLatch;

public class Thread06 extends Thread {
    private static final int countThread = 100;
    private static StringBuffer buffer = new StringBuffer();
    private static StringBuilder builder = new StringBuilder();
    private static CountDownLatch latch1 = new CountDownLatch(countThread);

    @Override
    public void run() {
        System.out.println("线程" +Thread.currentThread().getName());

        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("线程" +Thread.currentThread().getName() +"After Thead");    
        buffer.append("12345");
        builder.append("12345");
        latch1.countDown();
        System.out.println("线程" +Thread.currentThread().getName() +"run end--->");
    }

    public static void main(String[] args) throws InterruptedException {
        for (int i = 1; i <= countThread; i++) {
            Thread06 myThread = new Thread06();
            myThread.start();
        }
        latch1.await();
        System.out.println("StringBuffer-->:" + buffer.length() + "---》StringBuilder-->" + builder.length());

    }

}

执行结果:

 

自定义实现类似于CountDownLatch这样的类,当然自己试着写着玩的,肯定会有好多没有考虑到的

package cn.ok.http.utils;

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

import static cn.ok.http.utils.DaemonThreadTest.stringBuffer;
import static cn.ok.http.utils.DaemonThreadTest.stringBuilder;

public class DaemonThreadTest {

    private static int countThread = 1000;
    static DaemonThread daemoThread = new DaemonThread(countThread);
    static StringBuffer stringBuffer = new StringBuffer();   //线程安全
    static StringBuilder stringBuilder = new StringBuilder();  //非线程安全

    public static void main(String[] args) throws InterruptedException {
        System.out.println("main开始");

        StringThread buffer = new StringThread();
        for (int i = 0; i < countThread; i++) {
            Thread thread = new Thread(buffer);
            thread.start();
        }
        daemoThread.aWaite();
        System.out.println("Thred 执行完毕》》》》");
        System.out.println("StringBuffer-->:" + stringBuffer.length() + "---》StringBuilder-->" + stringBuilder.length());
        System.out.println("StringBuffer-->: " + stringBuffer.toString());
        System.out.println("StringBuilder-->:" + stringBuilder.toString());
    }
}

/**
 * desc:类似于ConutDownLatch类
 */
class DaemonThread {

    private int count; // 要运行线程个数
    private Lock lock = new ReentrantLock();
    private Boolean status = true;

    public int getCount() {
        return count;
    }

    public DaemonThread(int count) {
        this.count = count;
    }

    public void countDown() {
        lock.lock();
        try {
            this.count = this.count - 1;
            //  System.out.println("当前执行线程为Lock:" + Thread.currentThread().getName() + " countDown " + this.count);
        } catch (Exception e) {
        } finally {

            if (this.count == 0) {
                status = false;
            }
            lock.unlock();
        }
    }

    public void aWaite() throws InterruptedException {

        if (status) {
            Thread.sleep(4);
            aWaite();
        }
    }
}

/**
 * desc: 测试StringBuffer和StringBuilder类的线程安全性
 */
class StringThread implements Runnable {
    @Override
    public void run() {
        try {
            System.out.println("线程" + Thread.currentThread().getName());
            Thread.sleep(1000);
            for (int i = 0; i < 100; i++) {
                stringBuffer.append("ABC");
                stringBuilder.append("ABC");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        DaemonThreadTest.daemoThread.countDown();
    }

}


当然也可以直接这样用:

package book.thread.pool;


import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class MyRunnable implements Runnable {
    @Override
    public void run() {
        try {
            System.out.println("线程" + Thread.currentThread().getName());
            Thread.sleep(1000);
            for (int i = 0; i < 100; i++) {
                ExecutorServiceDemo.stringBuffer.append("ABC");
                ExecutorServiceDemo.stringBuilder.append("ABC");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class ExecutorServiceDemo {
    
    static StringBuffer stringBuffer = new StringBuffer();
    static StringBuilder stringBuilder = new StringBuilder();

    public static void main(String[] args) throws InterruptedException {

        int countThread = 1000;
        System.out.println("main 开始");
        // 创建一个线程池对象,控制要创建几个线程对象。

        ExecutorService pool = Executors.newFixedThreadPool(countThread);
        for (int i = 0; i < countThread; i++) {
            // 可以执行Runnable对象或者Callable对象代表的线程
            pool.submit(new MyRunnable());
        }
        //结束线程池
        pool.shutdown();


        //这2个,默认为main线程和守护线程 Thread.enumerate
        while (Thread.activeCount() != 2) {
        }
        System.out.println("StringBuffer-->:" + stringBuffer.length() + "---》StringBuilder-->" + stringBuilder.length());

        System.out.println("main退出");

    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值