Java 并发
Java非常重要的一个特性就是对CPU、缓存的控制,也就是对并发的控制相当强大。然而它也不是万能的,并发的解决方案只能局限在物理/软件资源的限制内,如带宽,CPU,内存等物理资源。对Java来说CPU的核数越大越好,代表着在并发时服务器的最大同时处理事件的数量。那么在单核机器中是否就意味着Java的并发无效呢?并不是,如果你在单核机器中建立一个线程池并去处理依旧可产生并发的效果,这是单核机器中操作系统的特殊处理
CPU资源的竞争问题
- volatile
- 乐观锁升级版,在cpu将处理完毕的缓冲区的数据返回给内存区时才上锁,其它核的cpu可以同时获得它并处理,但在处理完毕后无法将数据返回给内存区,因为返回内存区之前会先校验内存地址是否存在,如果已被更改过,则内存地址会变,那么将丢弃当前操作
- synchronized
- 悲观锁,为CAS和volatile读写的结合,CAS是Java 并发类库中的一个方法 CompareAndSet,类似于Redis中的 getset()方法。锁的切换方式在JDK1.7之前可通过参数调控,1.7之后调控参数去掉,由JVM自动调配
- 偏向锁:等待线程自旋,将锁与线程的绑定信息存在mark-word中,上下文切换(锁的拥有线程改变时)时,只需改变mark-word中的线程id即可,默认选择
- 轻量锁:等待线程自旋,获取锁时,将mark-word移动到堆中,使用引用指向堆中的mark-word,释放锁时,将mark-word移回栈中,如果在移回的过程中出错,一旦遇到竞争就升级为重量级
- 重量锁:等待线程阻塞,获取和释放锁的方式和轻量锁相同
锁的详细切换过程
- 检测Mark Word里面是不是当前线程的ID,如果是,表示当前线程处于偏向锁
- 如果不是,则使用CAS将当前线程的ID替换Mard Word,如果成功则表示当前线程获得偏向锁,置偏向标志为1
- 如果失败,则说明发生竞争,撤销偏向锁,进而升级为轻量级锁。
- 当前线程使用CAS将对象头的Mark Word替换为锁记录指针,如果成功,当前线程获得锁
- 如果失败,表示其他线程竞争锁,当前线程便尝试使用自旋来获取锁。
- 如果自旋成功则依然处于轻量级状态。
- 如果自旋失败,则升级为重量级锁。
线程通信JMM
- 线程通信实质上是对共享变量的读写操作,有两种线程通信的方法,分为共享内存和消息传递,Java采用的是共享内存。简单说就是一个线程把数据写入到内存中,另一个线程通过操作系统去内存中取出当前数据。例如Java中的 static 、单例 、 Exchanger和PipedReader/PipedWriter等都是常用的共享变量工厂。那么在线程通讯时为了保证数据的安全信,volatile和CAS成为了保证数据安全性、一致性的重要手段。
重排序
- Java在编译阶段会对代码进行重排序,在很多时候我们还是需要注意的。当然,我们很少能感知到的,CPU也会对指令进行重排序。有以下两条规则:
- 对有数据依赖的单线程操作不会重排序,基于happens-before,JSR-133内存模型
- 对无数据依赖,且不会影响执行结果的单线程可以重排序,基于as-if-serial
- 有两个注意点,final域的读写和构造函数的结束不能被重排序
线程的6个状态
- 就绪状态 在创建线程,start()之前
- 运行状态 线程执行时
- 阻塞状态 由synchronized造成,在获取不到锁时,具体的阻塞方式由jvm锁的选择确定,偏向锁轻量锁自旋,重量锁暂停(等待)。简单说就是在AQS中的线程
- 等待状态 由wait(),join()造成,由notify(),notifyall()解除
- 超时等待状态 由wait(long),sleep(long)造成,由notify(),notifyall()解除
- 终止状态 线程运行结束的状态
daemon
- daemon线程是普通线程的辅助,一旦进程中不存在普通线程,所有daemon线程立即终止
线程的启动
- 由父线程启动,一些参数默认复制父类,也可手动修改
线程的中断
- 前提为当前线程为等待状态或者阻塞状态
常用工具-原子更新类
- 很简单,直接上代码
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicIntegerArray;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicLongArray;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
/**
* 原子更新类
* 当有共享变量的更新需求时,可直接使用
* 原理:volatile+CAS
*/
public class AtomicTool {
//基本类型
private static AtomicBoolean bool = new AtomicBoolean();
private static AtomicLong longb = new AtomicLong();
private static AtomicInteger integer = new AtomicInteger();
//数组类型
private static AtomicLongArray longArray = new AtomicLongArray(10);
private static AtomicIntegerArray integerArray = new AtomicIntegerArray(10);
private static AtomicReferenceArray<User> referenceArray = new AtomicReferenceArray<User>(10);
//引用类型
private static AtomicReference<User> reference = new AtomicReference<User>();
//引用类型中的字段更新器
private static AtomicReferenceFieldUpdater<User, String> filedUpdater = AtomicReferenceFieldUpdater.newUpdater(User.class, String.class, "name");
private static AtomicIntegerFieldUpdater<User> integerFieldUpdater = AtomicIntegerFieldUpdater.newUpdater(User.class, "id");
private static AtomicLongFieldUpdater<User> longFieldUpdater = AtomicLongFieldUpdater.newUpdater(User.class, "old");
public static void main(String[] args) {
{
bool.set(true);
longb.set(100L);
integer.set(10);
int i = integer.getAndIncrement();
int i2 = integer.getAndDecrement();
int i3 = integer.getAndAdd(10);
boolean b = integer.compareAndSet(20, 2);
System.out.println(i);
System.out.println(i2);
System.out.println(i3);
System.out.println(b);
}
{
referenceArray.get(0);
referenceArray.getAndSet(0, new User());
referenceArray.set(0, new User());
referenceArray.compareAndSet(0, new User(), new User());
}
{
User user = new User();
reference.set(user);
reference.compareAndSet(user, new User());
reference.get();
}
{
User user = new User(1, "name",10L);
int prev = integerFieldUpdater.getAndIncrement(user);
int result = integerFieldUpdater.get(user);
int result4 = integer.addAndGet(10);
System.out.println(prev);
System.out.println(result);
System.out.println(result4);
long prev2 = longFieldUpdater.getAndIncrement(user);
long result2 = longFieldUpdater.get(user);
long result3 = longFieldUpdater.addAndGet(user, 10l);
System.out.println(prev2);
System.out.println(result2);
System.out.println(result3);
String prev3 = filedUpdater.getAndSet(user, "new name");
String result5 = filedUpdater.get(user);
filedUpdater.set(user, "new name");
boolean succeed = filedUpdater.compareAndSet(user, "new name", "most new name");
String result6 = filedUpdater.get(user);
System.out.println(prev3);
System.out.println(result5);
System.out.println(succeed);
System.out.println(result6);
}
}
static class User{
//必须为int,不可是Integer
public volatile int id;
//必须为long,不可是Long
public volatile long old;
public volatile String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getOld() {
return old;
}
public void setOld(Long old) {
this.old = old;
}
public User(int id, String name, Long old) {
super();
this.id = id;
this.name = name;
this.old = old;
}
public User() {
super();
}
}
public static AtomicBoolean getBool() {
return bool;
}
public static void setBool(AtomicBoolean bool) {
AtomicTool.bool = bool;
}
public static AtomicLong getLongb() {
return longb;
}
public static void setLongb(AtomicLong longb) {
AtomicTool.longb = longb;
}
public static AtomicInteger getInteger() {
return integer;
}
public static void setInteger(AtomicInteger integer) {
AtomicTool.integer = integer;
}
public static AtomicLongArray getLongArray() {
return longArray;
}
public static void setLongArray(AtomicLongArray longArray) {
AtomicTool.longArray = longArray;
}
public static AtomicIntegerArray getIntegerArray() {
return integerArray;
}
public static void setIntegerArray(AtomicIntegerArray integerArray) {
AtomicTool.integerArray = integerArray;
}
public static AtomicReferenceArray<User> getReferenceArray() {
return referenceArray;
}
public static void setReferenceArray(AtomicReferenceArray<User> referenceArray) {
AtomicTool.referenceArray = referenceArray;
}
public static AtomicReference<User> getReference() {
return reference;
}
public static void setReference(AtomicReference<User> reference) {
AtomicTool.reference = reference;
}
public static AtomicIntegerFieldUpdater<User> getIntegerFieldUpdater() {
return integerFieldUpdater;
}
public static void setIntegerFieldUpdater(
AtomicIntegerFieldUpdater<User> integerFieldUpdater) {
AtomicTool.integerFieldUpdater = integerFieldUpdater;
}
}
常用工具
- 基于AQS的实现类
- ReentrantLock
import java.util.Date;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* ReentrantLock基于AQS(双向队列)实现
* 可定义阻塞线程的排序规则
*/
public class ThreadReentrantLock {
private static final byte[] b = new byte[]{};
public static void main(String[] args) {
Lock lock = new ReentrantLock(true);
for (int i = 0; i < 10; i++) {
Thread r = new Thread(new Runnable() {
@Override
public void run() {
lockTest(lock);
// lockTestSync();
}
});
r.start();
}
}
private static void lockTest(Lock lock) {
try {
System.out.println("!!create thread" + Thread.currentThread().getId());
lock.lock();
lock.lock();
for (int i = 0; i < 4; i++) {
String info = new StringBuffer()
.append(Thread.currentThread().getId()).append(" name: ")
.append(Thread.currentThread().getName())
.append(" date: ")
.append(new Date().getTime())
.append(" i: ")
.append(i).toString();
System.out.println(info);
}
} catch (Exception e) {
lock.unlock();
lock.unlock();
} finally {
lock.unlock();
lock.unlock();
}
}
private static void lockTestSync() {
synchronized (b) {
synchronized (b) {
for (int i = 0; i < 4; i++) {
String info = new StringBuffer()
.append(Thread.currentThread().getId()).append(" name: ")
.append(Thread.currentThread().getName())
.append(" date: ")
.append(new Date().getTime())
.append(" i: ")
.append(i).toString();
System.out.println(info);
}
}
}
}
}
- ReentrantReadwriteLock
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* 读写锁
* 读锁和读锁不互斥,写锁和读锁/写锁都互斥
* 基于ASQ实现
*/
public class ThreadReentrantReadWriteLock {
public static void main(String[] args) {
final Queue3 q3 = new Queue3();
for (int i = 0; i < 3; i++) {
new Thread() {
public void run() {
while (true) {
q3.get();
}
}
}.start();
}
for (int i = 0; i < 3; i++) {
new Thread() {
public void run() {
while (true) {
q3.put(new Random().nextInt(10000));
}
}
}.start();
}
}
}
class Queue3 {
private Object data = null;// 共享数据,只能有一个线程能写该数据,但可以有多个线程同时读该数据。
private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
public void get() {
rwl.readLock().lock();// 上读锁,其他线程只能读不能写
System.out.println(Thread.currentThread().getName() + " be ready to read data!");
try {
Thread.sleep((long) (Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "have read data :" + data);
rwl.readLock().unlock(); // 释放读锁,最好放在finnaly里面
}
public void put(Object data) {
rwl.writeLock().lock();// 上写锁,不允许其他线程读也不允许写
System.out.println(Thread.currentThread().getName() + " be ready to write data!");
try {
Thread.sleep((long) (Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
this.data = data;
System.out.println(Thread.currentThread().getName() + " have write data: " + data);
rwl.writeLock().unlock();// 释放写锁
}
}
/**
* 读写锁模拟一个缓存器
*/
class CacheDemo {
private static Map<String, Object> map = new HashMap<String, Object>();// 缓存器
private static ReadWriteLock rwl = new ReentrantReadWriteLock();
public static void main(String[] args) {
get("1");
}
public static Object get(String id) {
Object value = null;
rwl.readLock().lock();// 首先开启读锁,从缓存中去取
try {
value = map.get(id);
if (value == null) { // 如果缓存中没有释放读锁,上写锁
rwl.readLock().unlock();
try {
rwl.writeLock().lock();
if (value == null) {
value = "aaa"; // 此时可以去数据库中查找,这里简单的模拟一下
}
} finally {
rwl.writeLock().unlock(); // 释放写锁
}
rwl.readLock().lock(); // 然后再上读锁
}
} finally {
rwl.readLock().unlock(); // 最后释放读锁
}
return value;
}
}
- CountdownLatch
import java.util.concurrent.CountDownLatch;
/**
* 用法类似CyclicBarrier
* 特性,可替代CyclicBarrier,但在不需要准确获取当前threadCount的话,CyclicBarrier更方便
*/
public class ThreadCountDownLatch {
public static void testCountDownLatch() {
int threadCount = 10;
final CountDownLatch latch = new CountDownLatch(threadCount);
for (int i = 0; i < threadCount; i++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程" + Thread.currentThread().getId() + "开始出发; count-" + latch.getCount());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程" + Thread.currentThread().getId() + "已到达终点; count-" + latch.getCount());
latch.countDown();
// try {
// latch.await();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println("10个线程已经执行完毕!开始计算排名");
}
}).start();
}
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("10个线程已经执行完毕!开始计算排名-");
}
public static void main(String[] args) {
testCountDownLatch();
}
}
- CyclicBarrier
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* 线程屏障
* 用法类似CountDownLatch
* 特性,会使所有线程等待在await()的执行部位,所有线程全部到时才会开启屏障。可以重置屏障
*/
public class ThreadCyclicBarrier {
private static Integer parties = 4;
private static Integer realParties = 4;
/**
* 共享变量
*/
private static Integer result = 0;
private static CyclicBarrier cyclicBarrier = new CyclicBarrier(parties, ()->{System.out.println("全部到达屏障,我被第一个执行");});
public static void main(String[] args) {
toBarrier();
ReentrantLock r = new ReentrantLock();
Condition c = r.newCondition();
r.lock();
try {
c.awaitNanos(1000000000l);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
r.unlock();
}
cyclicBarrier.reset();
toBarrier();
}
public static void toBarrier() {
for (int i = 0; i < realParties; i++) {
new Thread(()->{
try {
cyclicBarrier.await();
} catch (Exception e) {
e.printStackTrace();
}
result+=2;
System.out.println("全部到达屏障,开始处理数据,最新result:" + result);
}).start();
}
}
}
- Semaphore
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
/**
* Semaphore
* 可控制正在执行一段代码的数量,如控制程序并发访问量
*/
public class ThreadSemaphore {
private static final int THREAD_COUNT = 10;
private static ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_COUNT);
private static Semaphore s = new Semaphore(10, true);
public static void main(String[] args) {
System.out.println(s.isFair());
for (int i = 0; i < THREAD_COUNT; i++) {
threadPool.execute(()->{
try {
s.acquire();
System.out.println("save data; useful licence num:"+s.availablePermits()+"; waiting thread num:"+s.getQueueLength()
+ "; has waiting threads:" + s.hasQueuedThreads()) ;
s.release();
} catch (Exception e) {
e.printStackTrace();
}
});
}
threadPool.shutdown();
}
}
- FutureTask
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
/**
* Callable:和runnable的唯一不同在于有返回值
* FutureTask:和Callable的不同在于把get()和run()分开执行,并使get()阻塞到run()执行后才执行
*/
public class ThreadFutureTask {
public static void main(String[] args) {
executionTask("task");
callableDemo();
runnableToCallable();
}
/**
* futureTask Demo
*/
private static void executionTask(final String taskName) {
Callable<String> task = new Callable<String>() {
@Override
public String call() throws Exception {
return taskName;
}
};
FutureTask<String> futureTask = new FutureTask<String>(task);
new Thread(()->{
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
futureTask.run();
}).start();
try {
String result = futureTask.get(); //get()会阻塞到run()执行后才执行
System.out.println(result);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
/**
* CallableDemo
*/
public static void callableDemo() {
Callable<String> task = new Callable<String>() {
@Override
public String call() throws Exception {
System.out.println("test");
return "suc";
}
};
try {
String result = task.call();
System.out.println("result:"+result);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Runnable转Callable
*/
public static void runnableToCallable() {
try {
String s = Executors.callable(()->{System.out.println("into");}, "successed").call();
System.out.println(s);
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 手动进入等待/阻塞状态
- Locksupport / Condition(reentrantlock)
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;
/**
* LockSupport 手动控制当前线程进入/退出阻塞状态
* Condition 手动控制当前线程进入/退出等待状态
*/
public class ThreadLockSupport {
private static Byte[] b = new Byte[0];
private static Lock lock = new ReentrantLock();
private static Condition condition = lock.newCondition();
public static void main(String[] args) {
// lockSupportUtil();
conditionUtil();
}
/**
* 手动控制当前线程进入/退出阻塞状态LockSupport
*/
public static void lockSupportUtil(){
Thread r = new Thread(()->{
System.out.println(Thread.currentThread().getName() + " - parked");
LockSupport.park(); //当前线程进入阻塞状态
// LockSupport.parkNanos(3000000000L); //当前线程进入阻塞状态,超过3000000000L纳秒后自动退出阻塞
// LockSupport.parkUntil(new Date().getTime() + 3000); //当前线程进入阻塞状态,3秒后自动退出阻塞
});
r.start();
new Thread(()->{
System.out.println(r.getName() + " - unparked");
LockSupport.unpark(r);
}).start();
}
/**
* 手动控制当前线程进入/退出等待状态Condition
*/
public static void conditionUtil() {
for (int i = 0; i < 5; i++) {
new Thread(()->{
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + " - awaiting");
condition.await(); //当前线程进入等待状态,直到其他线程signal
// condition.awaitNanos(3000000000L); //当前线程进入等待状态,超过3000000000L纳秒后自动退出阻塞
// condition.awaitUntil(new Date(new Date().getTime() + 3000 )); //当前线程进入等待状态,3秒后自动退出阻塞
} catch (InterruptedException e) {
e.printStackTrace();
lock.unlock();
} finally {
lock.unlock();
}
}).start();
}
try {
synchronized (b) {
b.wait(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
lock.lock();
for (int i = 0; i < 5; i++) {
System.out.println(" - exit awaiting");
condition.signal(); //退出等待状态
}
lock.unlock();
}).start();
}
}
- 基于双端队列的任务分割
- Fork/Join
import java.util.Date;
import java.util.Vector;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask;
/**
* fork/join分隔并多线程完成任务
* 特性:自带线程池,更完美的分隔任务
*/
public class ThreadForkJoinUseful extends RecursiveTask<Integer>{
private static final long serialVersionUID = 1L;
private Integer middleNum;
/**
* true 任务总线,分隔任务
* false 分隔后的任务
*/
private Integer taskLevel;
public ThreadForkJoinUseful(Integer middleNum, Integer taskLevel) {
super();
this.middleNum = middleNum;
this.taskLevel = taskLevel;
}
@Override
protected Integer compute() {
Vector<ThreadForkJoinUseful> v = new Vector<ThreadForkJoinUseful>();
Integer result = 0;
switch (taskLevel) {
case 1 :
for (int i = 0; i < 100000; i++) {
v.add(new ThreadForkJoinUseful(1, 2));
}
for (ThreadForkJoinUseful threadForkJoinTestUseful : v) {
threadForkJoinTestUseful.fork();
int performResult = threadForkJoinTestUseful.join();
result += performResult;
}
System.out.println("task执行完成,返回result");
return result;
case 2 :
System.out.println("操作任务的线程为 : " + Thread.currentThread().getId());
return middleNum;
default :
System.out.println("操作异常,无次taskLevel");
return 0;
}
}
public static void main(String[] args) {
ForkJoinPool forkJoinPool = new ForkJoinPool(20);
Future<Integer> result = forkJoinPool.submit(new ThreadForkJoinUseful(1, 1));
try {
Long t1 = new Date().getTime();
System.out.println(result.get());
Long t2 = new Date().getTime();
System.out.println("time:"+(t2-t1));
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
forkJoinPool.shutdown();
}
}
- 线程池
- ThreadPoolExecutor原生线程池
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor.AbortPolicy;
import java.util.concurrent.TimeUnit;
class ThreadPool implements Runnable {
private static final String corePoolSize1 = "";// 池中所保存的线程数--基准数
private String corePoolSize2;
public ThreadPool(String corePoolSize2) {
super();
this.corePoolSize2 = corePoolSize2;
}
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (corePoolSize1) {
System.out.println(Thread.currentThread().getName()+"---->"+corePoolSize2);
}
}
/**
* <<任务队列>>
* 1.ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按 FIFO(先进先出)原则对元素进行排序。 ------有界队列
* 2.LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按FIFO (先进先出) 排序元素,吞吐量通常要高于ArrayBlockingQueue。
* 静态工厂方法Executors.newFixedThreadPool()使用了这个队列。 ------无界队列
* 3.SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,
* 吞吐量通常要高于LinkedBlockingQueue,静态工厂方法Executors.newCachedThreadPool使用了这个队列。 ------直接提交队列
* 4.PriorityBlockingQueue:一个具有优先级得无限阻塞队列。
*/
private static final BlockingQueue<Runnable> runnableTaskQueue = new ArrayBlockingQueue<Runnable>(100);// 用于保持任务的队列
private static final int corePoolSize = 3;// 池中所保存的线程数--基准数
private static final int maximumPoolSize = Integer.MAX_VALUE;// 池中允许创建的最大线程数
private static final long keepAliveTime = 60L; // 当线程数大于基准数时,此为终止前多余的空闲线程等待新任务的最长时间。
private static final TimeUnit milliseconds = TimeUnit.SECONDS;// keepAliveTime的单位
private static final RejectedExecutionHandler handler = new AbortPolicy();// 饱和策略
private static final ThreadFactory threadFactory = new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
// TODO Auto-generated method stub
return new Thread();
}
};// 设置创建线程的工厂
/**
* CallerRunsPolicy:只用调用者所在线程来运行任务
* DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务
* DiscardPolicy:不处理,丢弃掉
*/
public static void main(String[] args) throws InterruptedException {
ExecutorService threadsPool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize,
keepAliveTime, milliseconds, runnableTaskQueue, handler);
for (int i = 0; i < 100; i++) {
threadsPool.execute(new ThreadPool(i+""));
}
System.out.println("--------------------------"+runnableTaskQueue.size());
Thread.sleep(20);
System.out.println("--------------------------"+runnableTaskQueue.size());
threadsPool.shutdown();
}
}
- Executor封装后的线程池
package com.td.thread;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* ThreadPoolExecutor
* ScheduledThreadPoolExecutor
* Future
* Runnable
* Callable
* Executors
*/
public class ThreadExecutor extends Thread {
public void run() {
System.out.println(Thread.currentThread().getName() + "你要执行的task写在这个方法里");
}
public static void main(String[] args) {
// 每个线程需要大约1MB内存
// 创建一个单线程的线程池
// ExecutorService pool = Executors.newSingleThreadExecutor();
// 创建固定大小的线程池
// ExecutorService pool = Executors.newFixedThreadPool(2);
// 创建一个可缓存的线程池 : 线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。
ExecutorService pool = Executors.newCachedThreadPool();
// 创建一个大小无限的线程池 : 此线程池支持定时以及周期性执行任务的需求。
// ExecutorService pool = Executors.newScheduledThreadPool(3);
Thread t1 = new ThreadExecutor();
Thread t2 = new ThreadExecutor();
Thread t3 = new ThreadExecutor();
Thread t4 = new ThreadExecutor();
Thread t5 = new ThreadExecutor();
// 提交任务到threadsPool
pool.execute(t1);
pool.execute(t2);
pool.execute(t3);
pool.execute(t4);
Future<?> re = pool.submit(Executors.callable(t5, "change to callable succeeded"));
try {
System.out.println(re.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
// 关闭线程池
pool.shutdown();
}
}
- 线程通信工具
- Exchanger - PipedReader/PipedWriter
import java.io.IOException;
import java.io.PipedReader;
import java.io.PipedWriter;
import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* PipedReader/PipedInputStream
* Exchanger
* 区别,无
*/
public class ThreadPiped {
private static final Exchanger<String> exgr = new Exchanger<String>();
private static ExecutorService threadPool = Executors.newFixedThreadPool(2);
public static void main(String[] args) {
doPipedJob();
exchangerTest();
}
/**
* PipedReader/PipedInputStream,共享变量
*/
private static void doPipedJob() {
try (PipedWriter writer = new PipedWriter();
PipedReader reader = new PipedReader();) {
writer.connect(reader);
new Thread(() -> write(writer)).start();
Runnable runn = () -> read(reader);
runn.run();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void write(PipedWriter writer) {
try {
writer.write("writed str.");
} catch (IOException e) {
e.printStackTrace();
}
}
private static void read(PipedReader reader) {
int receive = 0;
try {
while ((receive = reader.read()) != -1) {
System.out.print((char) receive);
}
} catch (IOException e) {
}
}
/**
* Exchanger
*/
public static void exchangerTest() {
threadPool.execute(()->{
try {
String A = "银行流水A";
String B = exgr.exchange(A);
System.out.println(B);
} catch (Exception e) {
e.printStackTrace();
}
});
threadPool.execute(()->{
try {
String B = "银行流水B";
String A = exgr.exchange(B);
System.out.println(A);
} catch (Exception e) {
e.printStackTrace();
}
});
threadPool.shutdown();
}
}