线程工具类之Semaphore、FutureTask
2020-06-08 本文已影响0人
冰封陈韶
Semaphore 是JAVA多线程的一个工具类,主要是做流量控制的,它有acquire()、release()方法,前者是等待,后者是释放,下面用Semaphore实现数据库连接池;
public class DBpool{
private final static int POOL_SIZE = 10;
private static LinkedList<Connection> pool = new ArrayList<>();
//两个信号量,一个是满的,一个是针对空位的限流
private final Semaphore useful,useless;
//初始化线程池
static{
for(int i = 0;i < POOL_SIZE; i++){
//这里只是简单的连接,SqlConnectImpl实现了Connection接口
pool.addLast(SqlConnectImpl.fetchConnection());
}
}
public DBPool(){
useful = new Semaphore(DBpool.POOL_SIZE);
useless = new Semaphore(0);
}
public connection takeConnection(){
useful.acquire();
Connection conn;
//这里还是需要上锁
synchronized(pool){
conn = pool.removeFirst();
}
useless.release();
return conn;
}
public void returnConnection(Connection conn){
useless.acquire();
synchronized(pool){
conn = pool.addLast(conn);
}
usefull.release();
}
}
我们都知道,JAVA里面实现线程有两种方式,但是实现的线程方法都是没有返回值的,如果我们需要知道线程运行之后的结果,直接继承Thread或者实现Runnable接口是不行的,JDK还提供了一个Callable接口,可以返回运算结果,但是这个类线程里面没有构造方法,这里就需要FutureTask接口了
image.png
上图我们可以清晰的看到,我们可以使用Thread的构造方法将FutureTask传进去,然后调用call()方法获取到线程执行之后的数据,也可以调用Future里面的cancel()方法去中断线程,可以说FutureTask是一个很强大的线程工具类,但是调用cancel方法需要遵循JAVA线程规范,它的底层实现还是一个中断标志位,如果需要中断,需要在线程里面校验这个标志位,然后释放资源,做相应的处理。