线程状态图 :
图来自Java线程的6种状态及切换(透彻解说)
初始、就绪、运行、期待、阻塞(synchronized)、终止。
Thread.sleep(millis)肯定工夫后主动复原执行,不开释对象锁。
Object.wait()间接开释锁,始终期待,晓得notify()唤醒。
Thread1.join()示意运行的线程阻塞本人,期待Thread1执行完,再执行上面语句。
yield()让出cpu,不开释对象锁,进入就绪态,随时可能再次运行。
只有运行态和就绪态之间波及到CPU资源的切换。(即yield())
Thread开启的3种形式
Thread、Runnable、Callable
- Thread
最简略的一种,间接继承Thread,重写run办法。主类中new ThreadName().start();则进去就绪态。 Runnable
- 实现Runnable接口,重写run。主类中new RunnableName().start();
- 实现Runnable接口,重写run。主类中new Thread(new Runnable()).start();
- Thread类还有其余重载办法,如传入ThreadGoup,Runnable初始执行接口等等,以上两个最罕用。
Thread类也是实现了Runnable接口,实际上都是调用的Runnable接口的run()办法。
Callable
实现Callable接口,重写call()办法。创立FutureTask对象new FutureTask<>(CallableName);再new Thread(FutureTak).start();即可。FutureTask间接实现了Runnable和Future,所以理论调用的还是Thread(Runnable)构造方法。Callable接口只有一个办法V call();
Future接口蕴含cancel、isCancelled、isDone、get办法,用户获取返回值。(Futuretask对Future接口中的办法进行了重写)
Executor治理线程
- newFixedThreadPool固定大小的线程池
- newCachedThreadPool可扩大的
- newScheduledThreadPool可调度的,运行一次,反复运行等
- newSingleThreadPool单线程池
- newWorkStealingPool窃取别的线程池的线程
应用:
ExecutorService executor = Executors.newFixedThreadPool(3);Future<String> future = excutor.submit(Callable);//退出线程池future.get();//获取返回值
后盾线程deamon
定义:程序运行时在后盾提供通用服务的线程,这种线程并不属于不可或缺的局部。后盾线程运行的前提是必须有至多一个非后盾线程运行。
Thread.setDeamon(ture);必须在start()前设置。
java.util.concurrent包
CountDownLatch
同步多个工作,能够设置一个初值,任何在这个对象上调用wait()都将被阻塞,晓得值变成0,每个工作执行完调用countDown都使值减1。初始值不能重置,只能始终减上来。CyclicBarrier能够重置。
- CyclicBarrier
用于并发工作期待(相似join),如:idm多线程下载文件,最初进行文件整顿。能够重置初始值。 - DelayedQueue
用于延时队列(延时取出元素),队头的提早最长。 - PriorityBlockingQueue
优先级阻塞队列 - SemaPhore
信号量,容许n个工作同时拜访。
平安失败的原理
就是CopyOnWriteArrayList办法。
java.util.concurrent包上面的所有的类都是平安失败的
疾速失败的异样:ConcurrentModificationException
乐观锁: version、CAS(compareAndSwap)(Atomic包、ReentrankLock就是具体实现)
乐观锁: synchroinized
java.nio.*
基于缓冲的流。
次要组成:Channel,Buffer,Selector
clear,flip,compact区别:
ByteBuffer中有pos、lim、cap来记录缓冲应用状况。
- clear: position=0,limit=capacity,【清空缓冲】
- flip: limit=postion;position=0;【读指针挪动缓冲头】
- compact: 未读完的数据,压缩到缓冲头。【压缩未读完数据】
整体流程:获取通道,调配缓冲,clear,read一次,{flip,解决读到的数据,compact,read一次}
大括号{}中示意循环执行。
读的模板代码如下,根本大同小异。
void fileChannel(){ try { FileInputStream fis = new FileInputStream("content.txt"); FileChannel channel = fis.getChannel(); ByteBuffer byteBuffer = ByteBuffer.allocate(1024);//调配缓冲 //position置为0,limit置为capacity byteBuffer.clear(); int read = channel.read(byteBuffer); System.out.println(byteBuffer); while (read!=-1){ //limit置成position最初的位值,再指针position调成0 //从头读。(position、capacity、limit) byteBuffer.flip(); while(byteBuffer.hasRemaining()){ System.out.print((char)byteBuffer.get()); } //把未读完的数据压缩至0-position, //下一次从position到limit读 byteBuffer.compact(); read=channel.read(byteBuffer); } channel.close(); fis.close(); }catch (IOException e){ e.printStackTrace(); } }
fileChannel还有tryLock(),lock()和release()办法。tryLock为非阻塞式,得不到锁就立马返回
IO多路复用——selector【NIO的重点】
一个选择器治理多个Channel。
举荐优良博客:NIO的三大组件