java线程并发库

1.原子性操作类

在java.util.concurrent.atomic 包中有一系列的原子性操作类比如:AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference(使用AtomicReference可以实现对所有对象的原子引用及赋值.包括Double与Float,但不包括对其的计算.浮点的计算,只能依靠同步关键字或Lock接口来实现了)
等,这些类支持在单个变量上解除锁的线程安全编程。就是对其增加或减少的操作都是原子性的,不会因为并发而使值变得不可靠。

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

public class AtomicClass implements Runnable {
	private final Set<Integer> set = new HashSet<Integer>();
	private int i = 0;
	private final AtomicInteger aInteger = new AtomicInteger(0);

	@Override
	public void run() {
		while (true) {

			int number = i++;// 此时i自增不是原子性的,因为set里面有重复值
		int aint = aInteger.addAndGet(1);//此时对自增的操作是原子性的不会有存在值,到最后回报java.lang.OutOfMemoryError: Java heap space错误也不会有重复值的
			if (set.contains(/* number */aint)) {
				System.out.println("存在重复值:" + /* number */aint);
				System.exit(0);
			} else {
				set.add(/* number */aint);
			}
		}

	}

	public static void main(String[] args) {
		AtomicClass aClass = new AtomicClass();
		for (int i = 0; i < 3; i++) {
			new Thread(aClass).start();
		}
	}

}

线程池

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

public class ExecurtorsClass {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// 启动固定的线程池,里面有3个线程服务,同时为5个任务服务
		ExecutorService eService = Executors.newFixedThreadPool(3);
		for (int i = 0; i < 5; i++) {
			final int t = i;
			eService.execute(new Runnable() {

				@Override
				public void run() {
					for (int j = 0; j < 10; j++) {
						System.out.println("线程"
								+ Thread.currentThread().getName() + ":为第" + t
								+ "个任务服务,循环第" + j + "次");
					}
				}
			});
		}

		// 启动缓存线程池根据任务的个数动态生成服务线程个数
		ExecutorService eCacheService = Executors.newCachedThreadPool();
		for (int i = 0; i < 10; i++) {
			final int t = i;
			eCacheService.execute(new Runnable() {

				@Override
				public void run() {
					for (int j = 0; j < 10; j++) {
						System.out.println("线程"
								+ Thread.currentThread().getName() + ":为第" + t
								+ "个任务服务,循环第" + j + "次");
					}

				}
			});
		}
		// 启动单一缓存池,为多个任务服务
		ExecutorService eSingleService = Executors.newSingleThreadExecutor();
		for (int i = 0; i < 10; i++) {
			final int t = i;
			eSingleService.execute(new Runnable() {

				@Override
				public void run() {
					for (int j = 0; j < 10; j++) {
						System.out.println("线程"
								+ Thread.currentThread().getName() + ":为第" + t
								+ "个任务服务,循环第" + j + "次");
					}

				}
			});
		}
		// 线程池启动定时器,使用3个线程,3秒后执行
		Executors.newScheduledThreadPool(3).schedule(new Runnable() {

			@Override
			public void run() {
				System.out.println("线程" + Thread.currentThread().getName()
						+ "启动的闹铃!---叮叮叮");

			}
		}, 3, TimeUnit.SECONDS);
		// 线程池启动定时器,使用3个线程服务,5秒后执行,每隔3秒执行一次
		Executors.newScheduledThreadPool(3).scheduleAtFixedRate(new Runnable() {

			@Override
			public void run() {
				System.out.println("线程" + Thread.currentThread().getName()
						+ "启动的闹铃!---叮叮叮(固定频率还响)");

			}
		}, 5, 3, TimeUnit.SECONDS);
		// eService.shutdown();//等待服务线程都服务完毕停止各个线程
		// eService.shutdownNow();//立即停止线程池,并销毁各个服务线程
	}

}

java并发库中的锁技术

lock类

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


public class LockClass extends Thread {
	private int t = 5;


	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			// synchronized (this) {//使用synchronized来同步代码
			Lock lock = new ReentrantLock();//使用jdk1.5新特新锁来同步代码
			lock.lock();//打开锁
			try {//此处虽然没异常但以后代码中必须加因为,可能异常抛出我们应该使用finally释放锁
				if (t > 0) {


					try {
						Thread.sleep(1000);
					} catch (Exception e) {
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName() + ":"
							+ t--);


				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {//这个一定要有,如果有异常的话
				lock.unlock();//释放锁
			}
			/* } */


		}
	}


	public static void main(String[] args) {
		LockClass tClass = new LockClass();
		new Thread(tClass).start();
		new Thread(tClass).start();
		new Thread(tClass).start();
		new Thread(tClass).start();
		new Thread(tClass).start();
		new Thread(tClass).start();
		new Thread(tClass).start();
		new Thread(tClass).start();//启动多个线程好,测试是否同步
	}


}


ReadWriteLock类

import java.util.Random;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/***
 * 读写锁,多个读锁不互斥,读锁与写锁互斥,写锁与写锁互斥
 * 
 * @author Administrator
 * 
 */
public class ReadWriteLockTest {
	public static void main(String[] args) {
		final Queue3 q3 = new Queue3();
		for (int i = 0; i < 3; i++) {
			new Thread() {
				@Override
				public void run() {
					while (true) {
						q3.get();
					}
				}

			}.start();

			new Thread() {
				@Override
				public void run() {
					while (true) {
						q3.put(new Random().nextInt(10000));
					}
				}

			}.start();
		}

	}
}

class Queue3 {
	private Object data = null;// 共享数据,只能有一个线程能写该数据,但可以有多个线程同时读该数据。
	ReadWriteLock rwl = new ReentrantReadWriteLock();// 实例化读写锁

	public void get() {
		rwl.readLock().lock();
		try {
			System.out.println(Thread.currentThread().getName() + " 准备好读数据!");
			Thread.sleep((long) (Math.random() * 1000));
			System.out.println(Thread.currentThread().getName() + "已经读到数据:"
					+ data);
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			rwl.readLock().unlock();
		}
	}

	public void put(Object data) {

		rwl.writeLock().lock();
		try {
			System.out.println(Thread.currentThread().getName() + " 准备好写数据!");
			Thread.sleep((long) (Math.random() * 1000));
			this.data = data;
			System.out.println(Thread.currentThread().getName() + " 已经写数据: "
					+ data);
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			rwl.writeLock().unlock();
		}

	}
}
锁技术中的 Condition类实现进程间的通信

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

public class MutualClass {

	/**
	 * 子线程打印5次主线程打印10此如此循环15次
	 * 
	 * @param args
	 */

	public static void main(String[] args) {
		final Business business = new Business();
		new Thread(new Runnable() {

			@Override
			public void run() {
				for (int j = 0; j < 15; j++) {
					business.sub(j);
				}

			}
		}).start();
		for (int j = 0; j < 15; j++) {
			business.main(j);
		}

	}

}

class Business {
	private boolean falg = true;
	Lock lock = new ReentrantLock();// 实例化锁
	Condition condition = lock.newCondition();// 实例化Condition

	public void sub(int j) {
		lock.lock();// 打开锁
		try {

			while (!falg) {
				try {
					condition.await();// 相当于object中的wait(),等待
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			for (int i = 0; i < 5; i++) {
				System.out.println("子线程:打印" + i + "次,循环往复" + j + "次");
			}
			falg = false;
			condition.signal();// 相当于object中的notify(),唤醒
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			lock.unlock();// 解锁
		}

	}

	public void main(int j) {
		lock.lock();// 上锁
		try {

			while (falg) {
				try {
					condition.await();// 线程等待
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			for (int i = 0; i < 10; i++) {
				System.out.println("主线程:打印" + i + "次,循环往复" + j + "次");
			}
			falg = true;
			condition.signal();// 线程唤醒
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			lock.unlock();// 解锁
		}

	}

}


java5新线程同步工具类

Semaphore 通常用于限制可以访问某些资源(物理或逻辑的)的线程数目,控制线程并发的个数。例如,下面的类使用信号量控制对内容池的访问

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

public class SemaphoreTest {
	public static void main(String[] args) {
		ExecutorService service = Executors.newCachedThreadPool();
		final Semaphore sp = new Semaphore(3);
		for (int i = 0; i < 10; i++) {
			Runnable runnable = new Runnable() {
				@Override
				public void run() {
					try {
						sp.acquire();
					} catch (InterruptedException e1) {
						e1.printStackTrace();
					}
					System.out.println("线程" + Thread.currentThread().getName()
							+ "进入,当前已有" + (3 - sp.availablePermits()) + "个并发");
					try {
						Thread.sleep((long) (Math.random() * 10000));
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println("线程" + Thread.currentThread().getName()
							+ "即将离开");
					sp.release();
					// 下面代码有时候执行不准确,因为其没有和上面的代码合成原子单元
					System.out.println("线程" + Thread.currentThread().getName()
							+ "已离开,当前已有" + (3 - sp.availablePermits()) + "个并发");
				}
			};
			service.execute(runnable);
		}
	}

}


CyclicBarrier一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,直到达到预定公共屏障点才各自继续运行

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

public class CyclicBarrierTest {

	public static void main(String[] args) {
		ExecutorService service = Executors.newCachedThreadPool();
		final  CyclicBarrier cb = new CyclicBarrier(3);
		for(int i=0;i<3;i++){
			Runnable runnable = new Runnable(){
					public void run(){
					try {
						Thread.sleep((long)(Math.random()*10000));	
						System.out.println("线程" + Thread.currentThread().getName() + 
								"即将到达集合地点1,当前已有" + (cb.getNumberWaiting()+1) + "个已经到达," + (cb.getNumberWaiting()==2?"都到齐了,继续走啊":"正在等候"));						
						cb.await();
						
						Thread.sleep((long)(Math.random()*10000));	
						System.out.println("线程" + Thread.currentThread().getName() + 
								"即将到达集合地点2,当前已有" + (cb.getNumberWaiting()+1) + "个已经到达," + (cb.getNumberWaiting()==2?"都到齐了,继续走啊":"正在等候"));
						cb.await();	
						Thread.sleep((long)(Math.random()*10000));	
						System.out.println("线程" + Thread.currentThread().getName() + 
								"即将到达集合地点3,当前已有" + (cb.getNumberWaiting() + 1) + "个已经到达," + (cb.getNumberWaiting()==2?"都到齐了,继续走啊":"正在等候"));						
						cb.await();						
					} catch (Exception e) {
						e.printStackTrace();
					}				
				}
			};
			service.execute(runnable);
		}
		service.shutdown();
	}
}


CountDownLatch一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。用给定的计数 初始化CountDownLatch。到达某个时刻将继续各自运行.比如裁判打枪(计数一个定值),此时各个线程在等待,枪响然后各个线程一起继续跑

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

public class CountdownLatchTest {

	public static void main(String[] args) {
		ExecutorService service = Executors.newCachedThreadPool();
		final CountDownLatch cdOrder = new CountDownLatch(1);
		final CountDownLatch cdAnswer = new CountDownLatch(3);		
		for(int i=0;i<3;i++){
			Runnable runnable = new Runnable(){
					public void run(){
					try {
						System.out.println("线程" + Thread.currentThread().getName() + 
								"正准备接受命令");						
						cdOrder.await();
						System.out.println("线程" + Thread.currentThread().getName() + 
						"已接受命令");								
						Thread.sleep((long)(Math.random()*10000));	
						System.out.println("线程" + Thread.currentThread().getName() + 
								"回应命令处理结果");						
						cdAnswer.countDown();						
					} catch (Exception e) {
						e.printStackTrace();
					}				
				}
			};
			service.execute(runnable);
		}		
		try {
			Thread.sleep((long)(Math.random()*10000));
		
			System.out.println("线程" + Thread.currentThread().getName() + 
					"即将发布命令");						
			cdOrder.countDown();
			System.out.println("线程" + Thread.currentThread().getName() + 
			"已发送命令,正在等待结果");	
			cdAnswer.await();
			System.out.println("线程" + Thread.currentThread().getName() + 
			"已收到所有响应结果");	
		} catch (Exception e) {
			e.printStackTrace();
		}				
		service.shutdown();

	}
}

Exchanger元素进行配对和交换的线程的同步点。每个线程将条目上的某个方法呈现给exchange 方法,与伙伴线程进行匹配,并且在返回时接收其伙伴的对象,就是一个线程达到同步点等待另一个进程,然后交换数据,然后进行各自线程

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

public class ExchangerTest {

	public static void main(String[] args) {
		ExecutorService service = Executors.newCachedThreadPool();
		final Exchanger exchanger = new Exchanger();
		service.execute(new Runnable(){
			public void run() {
				try {				

					String data1 = "zxx";
					System.out.println("线程" + Thread.currentThread().getName() + 
					"正在把数据" + data1 +"换出去");
					Thread.sleep((long)(Math.random()*10000));
					String data2 = (String)exchanger.exchange(data1);
					System.out.println("线程" + Thread.currentThread().getName() + 
					"换回的数据为" + data2);
				}catch(Exception e){
					
				}
			}	
		});
		service.execute(new Runnable(){
			public void run() {
				try {				

					String data1 = "lhm";
					System.out.println("线程" + Thread.currentThread().getName() + 
					"正在把数据" + data1 +"换出去");
					Thread.sleep((long)(Math.random()*10000));					
					String data2 = (String)exchanger.exchange(data1);
					System.out.println("线程" + Thread.currentThread().getName() + 
					"换回的数据为" + data2);
				}catch(Exception e){
					
				}				
			}	
		});		
	}
}

java5线程并发库新特性阻塞列队ArrayBlockingQueue

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BlockingQueueTest {
	public static void main(String[] args) {
		final BlockingQueue queue = new ArrayBlockingQueue(3);
		for(int i=0;i<2;i++){
			new Thread(){
				public void run(){
					while(true){
						try {
							Thread.sleep((long)(Math.random()*1000));
							System.out.println(Thread.currentThread().getName() + "准备放数据!");							
							queue.put(1);
							System.out.println(Thread.currentThread().getName() + "已经放了数据," + 							
										"队列目前有" + queue.size() + "个数据");
						} catch (InterruptedException e) {
							e.printStackTrace();
						}

					}
				}
				
			}.start();
		}
		
		new Thread(){
			public void run(){
				while(true){
					try {
						//将此处的睡眠时间分别改为100和1000,观察运行结果
						Thread.sleep(1000);
						System.out.println(Thread.currentThread().getName() + "准备取数据!");
						queue.take();
						System.out.println(Thread.currentThread().getName() + "已经取走数据," + 							
								"队列目前有" + queue.size() + "个数据");					
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
			
		}.start();			
	}
}


java5线程并发库新特性集合类

关于并发包中的集合类

除队列外,此包还提供了设计用于多线程上下文中的 Collection 实现:ConcurrentHashMapConcurrentSkipListMapConcurrentSkipListSetCopyOnWriteArrayListCopyOnWriteArraySet。当期望许多线程访问一个给定 collection 时,ConcurrentHashMap 通常优于同步的HashMapConcurrentSkipListMap 通常优于同步的TreeMap。当期望的读数和遍历远远大于列表的更新数时,CopyOnWriteArrayList 优于同步的ArrayList

此包中与某些类一起使用的“Concurrent&rdquo前缀;是一种简写,表明与类似的“同步”类有所不同。例如,java.util.HashtableCollections.synchronizedMap(new HashMap())是同步的,但ConcurrentHashMap则是“并发的”。并发 collection 是线程安全的,但是不受单个排他锁的管理。在ConcurrentHashMap 这一特定情况下,它可以安全地允许进行任意数目的并发读取,以及数目可调的并发写入。需要通过单个锁不允许对 collection 的所有访问时,“同步”类是很有用的,其代价是较差的可伸缩性。在期望多个线程访问公共 collection 的其他情况中,通常“并发”版本要更好一些。当 collection 是未共享的,或者仅保持其他锁时 collection 是可访问的情况下,非同步 collection 则要更好一些。













  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值