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新线程同步工具类
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 实现:ConcurrentHashMap
、ConcurrentSkipListMap
、ConcurrentSkipListSet
、CopyOnWriteArrayList
和CopyOnWriteArraySet
。当期望许多线程访问一个给定 collection 时,ConcurrentHashMap 通常优于同步的HashMap,ConcurrentSkipListMap 通常优于同步的TreeMap。当期望的读数和遍历远远大于列表的更新数时,CopyOnWriteArrayList 优于同步的ArrayList。
此包中与某些类一起使用的“Concurrent&rdquo前缀;是一种简写,表明与类似的“同步”类有所不同。例如,java.util.Hashtable 和Collections.synchronizedMap(new HashMap())是同步的,但ConcurrentHashMap
则是“并发的”。并发 collection 是线程安全的,但是不受单个排他锁的管理。在ConcurrentHashMap 这一特定情况下,它可以安全地允许进行任意数目的并发读取,以及数目可调的并发写入。需要通过单个锁不允许对 collection 的所有访问时,“同步”类是很有用的,其代价是较差的可伸缩性。在期望多个线程访问公共 collection 的其他情况中,通常“并发”版本要更好一些。当 collection 是未共享的,或者仅保持其他锁时 collection 是可访问的情况下,非同步 collection 则要更好一些。