---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
1、ThreadLocal实现线程范围内的共享变量。
package com.xiaozhi.threadlocal;
import java.util.Random;
public class Test2 {
private static ThreadLocal<Integer> threadLocal=new ThreadLocal<Integer>();
public static void main(String[] args) {
new Thread(){
public void run() {
int data=new Random().nextInt();
threadLocal.set(data);
System.out.println(Thread.currentThread().getName()+":"+data);
new A().get();
new B().get();
}
}.start();
new Thread(){
public void run() {
int data=new Random().nextInt();
threadLocal.set(data);
System.out.println(Thread.currentThread().getName()+":"+data);
new A().get();
new B().get();
}
}.start();
}
static class A{
public void get()
{
System.out.println(Thread.currentThread().getName()+"--------------new A().get():"+threadLocal.get());
}
}
static class B{
public void get()
{
System.out.println(Thread.currentThread().getName()+"--------------new B().get():"+threadLocal.get());
}
}
}
2、线程池:可以保证只有固定数量的线程运行
package jingtianxiaozhi;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TreadPoolTest {
public static void main(String[] args) {
ExecutorService service=Executors.newFixedThreadPool(3);
for(int i=0;i<10;i++)
{
final int task=i;
service.execute(new Runnable() {
@Override
public void run() {
for(int j=0;j<10;j++)
System.out.println("任务是:"+task+"第"+j+"次循环");
}
});
}
service.shutdown();
}
}
3、定时器:做android开发时经常用到定时器的思想
package jingtianxiaozhi;
import java.util.Timer;
import java.util.TimerTask;
public class Test4 {
/*
* 定时器思想很重要
*/
public static void main(String[] args) {
class MyTimerTask extends TimerTask
{
public void run() {
System.out.println("bombing!");
new Timer().schedule(new MyTimerTask(), 1000);
}
}
new Timer().schedule(new MyTimerTask(), 10000);
int start=1;
while(true)
{
try {Thread.sleep(1000);} catch (InterruptedException e) {}
System.out.println(start++);
}
}
}
4、Callable和Future组合:
Future表示计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。计算完成后只能使用get()方法来获取结果。
package jingtianxiaozhi;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/*
* 线程池续
* Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。
* 计算完成后只能使用 get 方法来获取结果,如有必要,计算完成前可以阻塞此方法
*/
public class TestCallableFuture {
public static void main(String[] args) {
ExecutorService threadPool=Executors.newSingleThreadExecutor();
Future<String>future = threadPool.submit(new Callable<String>() {
@Override
public String call() throws Exception {
return "Callable Future";
}
});
try {System.out.println("hello "+future.get());} catch(Exception e) {}
threadPool.shutdown();
}
}
5、CompletionService
CompletionService就是将生产新的异步任务与使用已完成任务的结果分离开来的服务。
生产者submit执行的任务,使用者get已经完成的任务。并按照完成这些任务的顺序处理它们的结果。
package jingtianxiaozhi;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/*
* CompletionService就是
* ExecutorService的子类的一个装饰设计类。
* 将生产新的异步任务与使用已完成任务的结果分离开来的服务。
* 生产者 submit 执行的任务。使用者 take 已完成的任务,并按照完成这些任务的顺序处理它们的结果。
*/
public class TestCompletionService {
public static void main(String[] args) {
ExecutorService threadPool=Executors.newFixedThreadPool(3);
CompletionService<Integer>completionService=new ExecutorCompletionService<Integer>(threadPool);
for(int i=0;i<10;i++){
final int task=i;
completionService.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
Thread.sleep(new Random().nextInt(10000));
return task;
}
});
}
for(int i=0;i<10;i++)
{
try {System.out.println(completionService.take().get());} catch (Exception e) {}
}
threadPool.shutdown();
}
}
6、读写锁ReadWriteLock:
ReadWriteLock维护了一对相关的锁,一个用于只读操作,另一个用于写入操作。只要没有write,读取锁可以由多个reader线程同时保持。写入锁是独占的。
与互斥锁相比,读写锁允许对共享数据进行更高级别的并发访问。
package xiaozhijingtian;
import java.util.Random;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReadWriteLockTest {
public static void main(String[] args) {
final ReadWriteObject object=new ReadWriteObject();
for(int i=0;i<3;i++)
{
new Thread(){
public void run() {
while(true)
object.read();
};
}.start();
new Thread(){
public void run() {
while(true)
object.write(new Random().nextInt(10));
};
}.start();
}
}
}
class ReadWriteObject{
private int data;
private ReadWriteLock readWriteLock=new ReentrantReadWriteLock();
public void read()
{
readWriteLock.readLock().lock();
System.out.println(Thread.currentThread().getName()+"我正准备读呢");
try { Thread.sleep(new Random().nextInt(10000)); } catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName()+"读出来了:"+data);
readWriteLock.readLock().unlock();
}
public void write(int data)
{
readWriteLock.writeLock().lock();
System.out.println(Thread.currentThread().getName()+"我正准备写呢");
try { Thread.sleep(new Random().nextInt(10000)); } catch (InterruptedException e) {}
this.data=data;
System.out.println(Thread.currentThread().getName()+"写完了:"+data);
readWriteLock.writeLock().unlock();
}
}
用读写锁写一个缓存系统
package com.xiaozhi.threadlocal2;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Test3 {
public static void main(String[] args) {
}
}
class Cache{
private Map<String,Object>map=new HashMap<String, Object>();
private ReadWriteLock readWriteLock=new ReentrantReadWriteLock();
public Object get(String key){
readWriteLock.readLock().lock();
Object value = null;
try {
value = map.get(key);
if(value==null)
{
readWriteLock.readLock().unlock();
readWriteLock.writeLock().lock();
try {
if(value==null)
value="jingtianxiaozhi";//QueryDB(key)
} finally{
readWriteLock.writeLock().unlock();
}
readWriteLock.readLock().lock();
}
} finally{
readWriteLock.readLock().unlock();
}
return value;
}
}
7、Semaphore
一个计数信号量。从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个acquire(),然后再获取该许可。每一个release()添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不适用实际的许可对象,Semaphore只对可用许可的号码进行技术,并采取相应的行动。
下面是一个入门demo
package xiaozhijingtian;
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(){
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);
}
service.shutdown();
}
}
8、CyclicBarrier
一个同步辅助类,它允许一组线程互相等待,知道到达某个公共屏障点。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时CyclicBarrier很有用。因为barrier在释放等待线程后可以重用,所以称它为循环的barrier。
package jingtianxiaozhi;
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) { http://write.blog.csdn.net/postedit/21300753
e.printStackTrace();
}
}
};
service.execute(runnable);
}
service.shutdown();
}
}
9、CountDownLatch
一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。可以实现一个人(也可以是多个人)等待其他所有人都来通知他,这犹如一个计划需要多个领导都签字后才能继续向下实施。还可以实现一个人通知多个人的效果,类似裁判一声口令,运动员同时开始奔跑。
package jingtianxiaozhi;
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();
}
}
10、Exchange
可以在对中对元素进行配对和交换的线程的同步点。每个线程将条目上的某个方法呈现给exchange()方法,与伙伴线程进行匹配,并且在返回时候接受其伙伴的对象。
package jingtianxiaozhi;
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 = "白粉";
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 = "金钱";
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){
}
}
});
}
}
运行结果如下
线程pool-1-thread-1正在把数据白粉换出去
线程pool-1-thread-2正在把金钱换出去
线程pool-1-thread-2换回的东西为白粉
线程pool-1-thread-1换回的数据为金钱
---------------------- ASP.Net+Unity开发、 .Net培训、期待与您交流! ----------------------