从CRUD到高软

线程工具类之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线程规范,它的底层实现还是一个中断标志位,如果需要中断,需要在线程里面校验这个标志位,然后释放资源,做相应的处理。

上一篇下一篇

猜你喜欢

热点阅读