线程6种状态
1)new:初始状态,线程被构建,但还没有调用start()方法。
2)runnable:运行状态,java中将系统的运行状态和就绪状态统称为运行状态
3)blocked:阻塞状态,表示线程阻塞于锁 (synchronized)
4)waiting:等待状态,进入该状态表示该线程需要等待其它线程作出一些动作
(中断或者通知 , object.wait())
5)TIME_WAITING:超时等待状态,该状态不同于waiting,他是可以在指定时间自动返回的 sleep导致
6)terminal:终止状态,表示当前线程已经执行完毕
注意 加synchroized导致block状态
lock导致waiting状态
daemon线程
1)main线程在启动线程daemonrunner之后随着main方法执行完毕而终止,此时java虚拟机中已经没有非daemon线程,虚拟机退出。虚拟机中所有daemon线程立即终止。
2)在构建daemon程序时,不能依靠finally块来清理资源
3)suspend() stop()在调用时不会释放资源,而是占着资源进入休眠状态,这样容易引起死锁。stop()在终结一个线程时不会释放资源,因此可能保证线程进入不正常状态
等待/通知机制
1 基本流程
1)使用wait() notify() notifyall()时需要先对对象加锁。
2)调用wait()方法后,线程状态由runnable 变成waiting状态,并将当前线程放到当前对象的等待队列中
3)notify()或notifyall()方法调用后,等待线程依旧不会从wait()中返回,需要调用notify()或者notifyall()的线程释放锁后,等待线程才有机会从wait()中返回
4)notify()方法是将线程从等待队列放入到同步队列中,而nofityall()方法是将所有的等待线程从等待队列中放入同步队列,被移动的线程从waiting状态变为blocked状态
5)从wait()对象返回的前提是获得了对象的锁
2 经典伪代码
等待方伪代码
1)synchronized(对象){
while(判断条件不足){
对象.await();
}
doSomeThing();
}
唤醒方伪代码
2) synchronized(对象){
判断满足条件
对象.notify();
}
3管道输入输出流
管道输入/输出流和普通文本输入输出流或者网络输入/输出流的不同之处在于,他主要用于线程之间的数据传输,主要介质为内存
out.conn
4join()方法的使用
如果一个线程a使用了 thread.join()那么它的含义是当前线程a等待thread线程终止后才从join()方法返回
5 等待超时
调用某个方法时等待一段时间,如果该方法能够在给定的时间内返回结果,那么将结果立刻返回,反之则返回默认结果
伪代码
public synchronized Object get(long millons){
long future = system.millons+millons
long remaining=millons;
while(result==null&&remaining>0){
wait(remaining);
remaining=future-system.millons;
}
return result;
}
6 线程安全的连接池实例
public class ConnectionPool{
private LinkedList pool = new LinkedList();
private static int initCapacity=10;
public ConnectionPool(){
//初始化连接池
for(int i=0;i<initCapacity;i++){
pool.addLast(ConnectionDriver.getConnection());
}
}
//释放连接池
public void ReleaseConnection(Connection connection){
Synchronized(pool){
pool.addLast(connection);
this.notify();
}
}
}
//获取连接池
public Connection fetchConnection(long millons){
long remaining = millons;
long future = System.currentMillons+millons;
Synchronized(pool){
while(pool.isempty()&&remaining>0){
pool.wait(millons);
remaining= System.currentMillons-future;
}
Connection conn=null;
if(!pool.isEmpty()){
conn = pool.removeFirst();
}
return conn;
}
}