`

java线程并发库

 
阅读更多

java线程并发库:Java5以后提供在并发编程中很常用的实用工具类,这些工具类在java.util.concurrent包下面。

 

  • java.util.concurrent.atomic包

支持在单个变量上解除锁的线程安全编程。可以对基本类型、数组中的基本类型、类中的基本类型等进行操作。

 

  • 线程池

创建一个只有一个线程的线程池,与单线程一样,但好处是保证池子里有一个线程
当线程意外死亡,会自动产生一个替补线程,始终有一个线程存活

ExecutorService threadPool = Executors.newSingleThreadExecutor();

 创建一个拥有固定线程数的线程池

ExecutorService threadPool = Executors.newFixedThreadPool(3);

 创建一个缓存线程池,线程池中的线程数根据任务多少自动增删,动态变化

ExecutorService threadPool = Executors.newCachedThreadPool();

 往线程池添加任务

threadPool.execute(new Runnable() {
    public void run() {
    }
});

 关闭线程池

threadPool.shutdown();//线程全部空闲,没有任务就关闭线程池
threadPool.shutdownNow();//不管任务有没有做完,都关掉

 

  • Callable与Future

Callable与Future是为了获取线程的返回结果

Future取得的结果类型和Callable返回的结果类型必须一致,这是通过泛型来实现的。
Callable要采用ExecutorSevice的submit方法提交,返回的future对象可以取消任务。

ExecutorService threadPool = Executors.newSingleThreadExecutor();
		Future<String> future = threadPool.submit(
				new Callable<String>() {
					public String call() throws Exception {
						Thread.sleep(200);
						return "hello";
					};
		});
		System.out.println("等待结果");
		try {
			System.out.println("拿到结果:"+future.get());
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}

CompletionService用于提交一组Callable任务,其take方法返回已完成的一个Callable任务对应的Future对象。

 

  • Lock

Lock比传统线程模型中的synchronized更加面向对象,锁本身也是一个对象,两个线程执行的代码要实现同步互斥效果,就要使用同一个锁对象。锁要上在要操作的资源类的内部方法中,而不是线程代码中。

Lock lock = new ReentrantLock();	
lock.lock();
//代码。。。。。
lock.unlock();

读写锁,分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,写锁与写锁互斥。
如果你的代码只读数据,可以很多人同时读,但不能同时写,那就上读锁;如果你的代码修改数据,只能有一个人在写,且不能同时读取,那就上写锁。

ReadWriteLock rwl = new ReentrantReadWriteLock();

 

  • Condition

Condition的功能类似在传统线程技术中的Object.wait()和Object.natify()的功能,传统线程技术实现的互斥只能一个线程单独干,不能说这个线程干完了通知另一个线程来干,Condition就是解决这个问题的,实现线程间的通信。

相关方法:

Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
condition.await();
condition.signal();

一个锁内部可以有多个Condition,即有多路等待和通知,可以参看jdk1.5提供的Lock与Condition实现的可阻塞队列的应用案例。

 

  • Semaphore

Semaphore可以维护当前访问自身的线程个数,并且提供了同步机制。semaphore实现的功能类似于厕所里有5个坑,有10个人要上厕所,同时就只能有5个人占用,当5个人中的任何一个让开后,其中在等待的另外5个人中又有一个可以占用了。

 

  • CyclicBarrier

一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。
CyclicBarrier 支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作 很有用。

 

  • CountdownLatch

一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。 用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达零之前,await 方法会一直受阻塞。之后,会释放所有等待的线程,await 的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。如果需要重置计数,请考虑使用 CyclicBarrier。
CountDownLatch 是一个通用同步工具,它有很多用途。将计数 1 初始化的 CountDownLatch 用作一个简单的开/关锁存器,或入口:在通过调用 countDown() 的线程打开入口前,所有调用 await 的线程都一直在入口处等待。用 N 初始化的 CountDownLatch 可以使一个线程在 N 个线程完成某项操作之前一直等待,或者使其在某项操作完成 N 次之前一直等待。

 

  • Exchanger

用于实现两个人之间的数据交换,每个人在完成一定的事务后想与对方交换数据,第一个先拿出数据的人会一直等待第二个人,直到第二个人拿着数据到来时,才能彼此交换数据。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics