本文主要是介绍JavaEE 第15节 JUC相关组件介绍,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
前言:
Callable
ReentrantLock
Semaphore
CountDownLatch
前言:
在Java中,JUC(包路径:java.util.concurrent)是一个用于并发编程的包,提供了线程安全的集合类、同步工具、并发执行框架和原子变量等,以简化和增强多线程编程的性能和可靠性。接下来介绍的这几个组件使用起来都比较简单。
Callable
Callable是一个接口,你可以理解成它是一个带有返回值的Runnable。
如图,Runnable和Callable的创建对比:
Thread类没有关于Callable的构造方法。原因在于需要通过Callable的实例创建FutureTask的实例才行:
public class CallableTest {public static void main(String[] args) throws InterruptedException, ExecutionException {Callable<Integer> callable=new Callable<Integer>() {@Overridepublic Integer call() throws Exception {System.out.println("hehhe");return 10;}};/**在创建线程的时候,多出了创建FutureTask的对象这一步*/FutureTask<Integer> futureTask=new FutureTask<>(callable);Thread thread=new Thread(futureTask);thread.start();thread.join();/*get方法可以获取到返回值*/int ret=futureTask.get();System.out.println("thread:"+ret);}
}
FutureTask是一个类,它的get方法可以获取call方法的返回值。
执行结果:
hehhe
thread:10
ReentrantLock
除了synchronized,Java标准库开提供了其他方式对线程进行加锁的操作。
比如:Excuters(第10节线程池讲过)、Semaphore(等一下会讲)、ReentrantLock(当前正题)等。
ReentrantLock是一个类(需要创建对象使用),与synchronized对比,ReentrantLock的区别:
- 加锁方式:需要用到lock()/unlock()来上锁解锁,因此为了避免死锁,最好把unlock()放到finally块中。
- tryLock:ReentrantLock提供了tryLock(),调用此方法,如果加锁失败,当前线程不会进入阻塞状态,而是直接返回,执行别的任务。
- 公平锁:ReentrantLock默认是不公平锁,不过可以在使用构造方法的时候设置成公平锁。
- 更精确的通知:ReentrantLock实现了Condition接口,在这个接口中,提供了一组方法,可以精确的唤醒某个满足特定条件的线程。而synchronized只能随机或全部唤醒。
Semaphore
Semaphore是计算机的一个专业术语,意为“信号量”。
它是一个控制资源访问的同步类工具。它可以限制同时访问某一个特定资源的总线程数量,保证多个线程可以有序的访问共享资源。
举个形象的例子:
在停车场的入口,我们通常会看到这个显示剩余车位的指示牌:
Semaphore就可以类比成这个指示牌。用了这个指示牌,外面的车子就不会无脑的开进去,在车位满了的时候就不会出现拥堵。
Semaphore的使用方式:
public class SemaphoreTest {public static void main(String[] args) {Semaphore semaphore=new Semaphore(4);for (int i = 0; i <20 ; i++) {int id=i;Thread t=new Thread(()->{try {System.out.println("申请资源");semaphore.acquire();//申请资源的方法System.out.println("执行任务:"+id);System.out.println("释放资源");semaphore.release();//释放资源的方法} catch (InterruptedException e) {e.printStackTrace();}});t.start();}}
}
如果Semaphore构造方法的参数设置成1,那么它就变成了一个加锁操作,一个线程在完成了任务后,其他线程才可以继续执行。
CountDownLatch
CountDownLatch是JUC中的一个同步辅助类,用它的构造方法可以设置一个任务数量,每次执行完一个任务,可以调用它自带的contDown()方法任务计数器会-1。当任务计数器为0的时候,可以唤醒其他线程(调用了CountDownLatch类的'await()'方法的线程,这个方法可以让调用它的线程进入睡眠直到任务计数器减为0)。
代码演示:
public class JUCcountDown {public static void main(String[] args) throws InterruptedException {ExecutorService service= Executors.newFixedThreadPool(4);CountDownLatch latch=new CountDownLatch(20);for (int i = 0; i <20 ; i++) {int id=i;service.submit(()->{System.out.println("执行任务:"+id);try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("任务:"+id+"执行完毕");latch.countDown();//计数器-1});}//主线程进入睡眠,计数器为0才会苏醒latch.await();System.out.println("所有任务执行完毕!");}
}
这篇关于JavaEE 第15节 JUC相关组件介绍的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!