Grails/java单资源池线程队列

Grails/java单资源池线程队列,java,grails,threadpool,Java,Grails,Threadpool,我正在尝试设置一个服务器,从设备提供真正的随机数,Quantis-Quantum random number Generator。我使用Grails框架构建了web应用程序,运行在Ubuntu上的Tomcat服务器上 因为只有一个设备,我必须安排访问它的线程,对吗?因此,我在调用这个设备的函数(ReadInt、ReadDouble、ReadFloat)上设置了信号量(带有1个资源)。包含这些函数的对象被称为Quantis,存储在Grails应用程序的Java源代码包中,它作为一个单例实现;然后,

我正在尝试设置一个服务器,从设备提供真正的随机数,
Quantis-Quantum random number Generator
。我使用Grails框架构建了web应用程序,运行在
Ubuntu
上的
Tomcat
服务器上

因为只有一个设备,我必须安排访问它的线程,对吗?因此,我在调用这个设备的函数(
ReadInt、ReadDouble、ReadFloat
)上设置了信号量(带有1个资源)。包含这些函数的对象被称为
Quantis
,存储在Grails应用程序的Java源代码包中,它作为一个单例实现;然后,控制器将调用此对象及其函数的实例。然后,这些函数中的每一个都将调用系统上的Quantis库来从设备读取流首先,“它将崩溃”是对发生的情况的糟糕描述。有例外吗?到底发生了什么

其次,您确定需要同步对API的访问吗。如果它提供了一个JavaAPI,那么这个API很有可能已经被同步,并且不需要您的信号量

第三,如果您获取了一个信号量,您应该在finally块中释放它。这保证了无论在try块中发生什么,它都会被释放:

ticket.acquire();
try {
    ...
}
catch (...) 
finally {
    ticket.release();
}
第四:我不明白while(true)循环的意义。它唯一循环的时间是当出现中断异常时。而InterruptedException正是用来通知线程它应该尽快停止执行的。所以你的方法应该抛出这个异常,而不是接受它

最后,您应该学习Java命名约定并坚持它们。方法以小写字母开头

如果您确实需要同步访问,那么下面是我将如何重写该方法:

public int readInt(int min, int max) throws QuantisException, InterruptedException {
    ticket.acquire();
    try {
        return quantisReadScaledInt(deviceType.getType(), deviceNumber, min, max);
    }
    finally {
        ticket.release();
    }
}
如果要确保只有一个线程可以访问本机库函数,请使用以下类:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

public class SingleThreadAccess {
    public static final SingleThreadAccess INSTANCE = new SingleThreadAccess();

    private ExecutorService executor;

    // to be called by ServletContextListener.contextInitialized()
    public void init() {
        executor = Executors.newSingleThreadExecutor();
    }

    // to be called by ServletContextListener.contextDestroyed()
    public void shutdown() {
        executor.shutdown();
        try {
            executor.awaitTermination(2L,TimeUnit.SECONDS);
        }
        catch (InterruptedException e) {
        }
        executor.shutdownNow();
    }

    public int readInt(int min, int max) throws QuantisException, InterruptedException {
        Callable<Integer> task = new Callable<Integer>() {
            @Override
            public Integer call() throws QuantisException {
                return quantisReadScaledInt(deviceType.getType(), deviceNumber, min, max);
            }
        };
        Future<Integer> future = executor.submit(task);
        try {
            future.get();
        }
        catch (ExecutionException e) {
            unwrap(e);
        }
    }

    private void unwrap(ExecutionException e) throws QuantisException {
        Throwable t = e.getCause();
        if (t instanceof QuantisException) {
            throw (QuantisException) t;
        }
        throw new RuntimeException(e);
    }
}
import java.util.concurrent.Callable;
导入java.util.concurrent.ExecutionException;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.Future;
导入java.util.concurrent.TimeUnit;
公共类单线程访问{
公共静态最终SingleThreadAccess实例=新SingleThreadAccess();
私人遗嘱执行人;
//由ServletContextListener.contextInitialized()调用
公共void init(){
executor=Executors.newSingleThreadExecutor();
}
//由ServletContextListener.contextDestroyed()调用
公共空间关闭(){
executor.shutdown();
试一试{
执行器等待终止(2L,时间单位秒);
}
捕捉(中断异常e){
}
执行者。关机现在();
}
public int readInt(int min,int max)抛出QuantisException,InterruptedException{
可调用任务=新的可调用任务(){
@凌驾
公共整数调用()引发QuantisexException{
返回QuantitysReadScaleDint(deviceType.getType(),deviceNumber,min,max);
}
};
未来=执行者提交(任务);
试一试{
future.get();
}
捕获(执行例外){
展开(e);
}
}
私有无效展开(ExecutionException e)抛出QuantiseException{
可丢弃的t=e.getCause();
if(量化异常的t实例){
投掷(量化感受)t;
}
抛出新的运行时异常(e);
}
}
首先,“它将崩溃”是对所发生情况的拙劣描述。有例外吗?到底发生了什么

其次,您确定需要同步对API的访问吗。如果它提供了一个JavaAPI,那么这个API很有可能已经被同步,并且不需要您的信号量

第三,如果您获取了一个信号量,您应该在finally块中释放它。这保证了无论在try块中发生什么,它都会被释放:

ticket.acquire();
try {
    ...
}
catch (...) 
finally {
    ticket.release();
}
第四:我不明白while(true)循环的意义。它唯一循环的时间是当出现中断异常时。而InterruptedException正是用来通知线程它应该尽快停止执行的。所以你的方法应该抛出这个异常,而不是接受它

最后,您应该学习Java命名约定并坚持它们。方法以小写字母开头

如果您确实需要同步访问,那么下面是我将如何重写该方法:

public int readInt(int min, int max) throws QuantisException, InterruptedException {
    ticket.acquire();
    try {
        return quantisReadScaledInt(deviceType.getType(), deviceNumber, min, max);
    }
    finally {
        ticket.release();
    }
}
如果要确保只有一个线程可以访问本机库函数,请使用以下类:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

public class SingleThreadAccess {
    public static final SingleThreadAccess INSTANCE = new SingleThreadAccess();

    private ExecutorService executor;

    // to be called by ServletContextListener.contextInitialized()
    public void init() {
        executor = Executors.newSingleThreadExecutor();
    }

    // to be called by ServletContextListener.contextDestroyed()
    public void shutdown() {
        executor.shutdown();
        try {
            executor.awaitTermination(2L,TimeUnit.SECONDS);
        }
        catch (InterruptedException e) {
        }
        executor.shutdownNow();
    }

    public int readInt(int min, int max) throws QuantisException, InterruptedException {
        Callable<Integer> task = new Callable<Integer>() {
            @Override
            public Integer call() throws QuantisException {
                return quantisReadScaledInt(deviceType.getType(), deviceNumber, min, max);
            }
        };
        Future<Integer> future = executor.submit(task);
        try {
            future.get();
        }
        catch (ExecutionException e) {
            unwrap(e);
        }
    }

    private void unwrap(ExecutionException e) throws QuantisException {
        Throwable t = e.getCause();
        if (t instanceof QuantisException) {
            throw (QuantisException) t;
        }
        throw new RuntimeException(e);
    }
}
import java.util.concurrent.Callable;
导入java.util.concurrent.ExecutionException;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.Future;
导入java.util.concurrent.TimeUnit;
公共类单线程访问{
公共静态最终SingleThreadAccess实例=新SingleThreadAccess();
私人遗嘱执行人;
//由ServletContextListener.contextInitialized()调用
公共void init(){
executor=Executors.newSingleThreadExecutor();
}
//由ServletContextListener.contextDestroyed()调用
公共空间关闭(){
executor.shutdown();
试一试{
执行器等待终止(2L,时间单位秒);
}
捕捉(中断异常e){
}
执行者。关机现在();
}
public int readInt(int min,int max)抛出QuantisException,InterruptedException{
可调用任务=新的可调用任务(){
@凌驾
公共整数调用()引发QuantisexException{
返回QuantitysReadScaleDint(deviceType.getType(),deviceNumber,min,max);
}
};
未来=执行者提交(任务);
试一试{
future.get();
}