Java EE——JUC和信号量

JUC

其是单词缩写,全称是java.util.concurrent
concurrent的意思是并发,这个包放的都是多线程相关的

Callable接口

和Runnable接口类似,都是实现一个任务,不过Callable接口的任务带返回值

demo

public static void main(String[] args) throws Exception {
	Callable<Integer> callable = new Callable<Integer>() {
	    @Override
	    public Integer call() throws Exception {
	        int sum = 0;
	        for (int i = 1; i <= 1000; i++) {
	            sum += i;
	        }
	        return sum;
	    }
	};
	FutureTask<Integer> futureTask = new FutureTask<>(callable);
	Thread t = new Thread(futureTask);
	t.start();
	System.out.println(futureTask.get());
}

我们的Thread类并不能直接传入Callable对象,而是要中间通过FutureTask进行转化,而且FutureTask也可以调用get方法得到Callable的返回值

ReentrantLock

是可重入锁

demo

public static void main(String[] args) {
	ReentrantLock locker = new ReentrantLock(true);
	try{
	   //locker.lock();
	   locker.tryLock();
	} finally {
	   locker.unlock();
	}
}

ReentrantLock的加锁和解锁过程是独立的,因此最好用try和finally包裹,否则这两者中间如果有return就会执行不到unlock

ReentrantLock还有tryLock方法,也就是尝试加锁,如果加锁失败了,就放弃加锁,也可以传入一个时间参数,如果加锁失败,就等一会,过了这个时间就放弃

在Reentrant构造方法中传入true,可以成为公平锁

ReentrantLock是搭配Condition类进行唤醒线程的,可以指定哪个线程唤醒

信号量

本身是一个计数器,统计可用资源的个数
信号量的基本操作有两个,P操作申请资源,可用资源就减一,V操作释放资源,可用资源就加一
锁是一个特殊的信号量,可用资源数只有一

semaphore

是java标准库中的类,将操作系统的信号量封装了起来

demo

public static void main(String[] args) throws InterruptedException {
    Semaphore semaphore = new Semaphore(4);
    semaphore.acquire();//p操作
    System.out.println("p");
    semaphore.acquire();//p操作
    System.out.println("p");
    semaphore.acquire();//p操作
    System.out.println("p");
    semaphore.acquire();//p操作
    System.out.println("p");
    semaphore.acquire();//p操作
    System.out.println("p");
    semaphore.release();//v操作
}

用构造方法创建一个semaphore对象,传入的值就是总共有的信号量,调用acquire方法就相当于p操作,调用release方法就相当于v操作,当计数器的值变成0时,那么就会阻塞等待,直到别的线程调用release

CountDownLatch

用来统计分块执行的任务是否完成

相当于跑步比赛,每有一个人到终点就撞线一次,直到撞线的次数等于参加比赛的总人数,比赛就结束了。

实际应用场景:一个服务器负责多个服务器的数据的组织串联,使用CountDownLatch可以确认什么时候所有服务器的数据都传输完毕

demo

public static void main(String[] args) throws InterruptedException {
    CountDownLatch countDownLatch = new CountDownLatch(10);
    for (int i = 0; i < 10; i++) {
        Thread t = new Thread(() -> {
            System.out.println("开始执行任务" + Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("结束执行任务" + Thread.currentThread().getName());
            countDownLatch.countDown();
        });
        t.start();
    }
    countDownLatch.await();
    System.out.println("所有任务执行完毕");
}

在这个演示中,创建CountDownLatch统计十个线程分别完成任务,当一个线程执行完任务就调用countDown方法,然后调用await方法就可以使代码阻塞等待到所有线程都撞线完成,也就执行完所有的任务了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值