如何在定义的线程(池)上 运行 class 的方法?
How to run the methods of a class on a defined thread(pool)?
我正在编写 classes 系列,全部使用相机。 每个class有4个基本方法来初始化、启动、停止或释放相机。
我想运行这些方法在后台线程。但我正在努力寻找一种简单的方法来做到这一点。
我发现的唯一方法是使用定义为
的通用 ExecutorService
ExecutorService backgroundThread = Executors.newSingleThreadExecutor();
然后,我必须 将每个方法的代码 包装成这样:
public void start(){
AbstractLight.backgroundThread.execute(new Runnable(){
public void run(){
//write "start method" code here
}
});
}
我想有更聪明的方法可以做到这一点,但我不知道。有人有办法做到这一点吗?
谢谢
您可以使用 Queue
方法调用以及 Router
来确定要调用哪个 class 方法:
public interface Camera {
public void init();
public void start();
public void stop();
public void release();
}
public class Router implements Runnable {
private final EnumMap<CameraType, Camera> cameras = new EnumMap<>(CameraType.class);
private final BlockingQueue<RouterInvocation> queue = new LinkedBlockingQueue<>();
public enum CameraType {
CAMERA1, CAMERA2, //etc
}
private enum CameraMethod {
INIT, START, STOP, RELEASE
}
private class RouterInvocation {
public final Camera camera;
public final CameraMethod cameraMethod;
public RouterInvocation(Camera c, CameraMethod cm) {
this.camera = c;
this.cameraMethod = cm;
}
}
// similar methods for start, stop, release
public void init(CameraType cameraType) {
queue.offer(new RouterInvocation(cameras.get(cameraType), INIT);
}
public void run() {
try {
while(true) {
// wait for next RouterInvocation
RouterInvocation i = queue.take();
if(i.cameraType == INIT) {
i.camera.init();
} else if // same for remaining methods
}
} catch(InterruptedException ex) {
return;
}
}
}
的好处是你只需要提交一个Runnable
(Router
)到ExecutorService
- 然后Router
负责调用合适的方法来自适当的 Camera
实施。
如果您决定要多个线程处理队列,那么您可以在多个 Routers
之间共享队列,或者我的建议是将 ExecutorService
移动到 [=12] =](因此 Router
不再实现 Runnable
而是创建内部 Runnables
来处理队列)。
您可以创建一个包含这些方法的 'async' 版本的摘要 parent class。
从一个抽象的 parent class 开始,然后将它们中的每一个都包装在它们自己的 运行nable 异步版本中。现在,每当您从抽象 parent 继承时,每个都会自动拥有自己的 运行nable。然后您可以将它们放入执行程序或 parent.
中您需要的任何内容
public abstract class CameraParent
{
public abstract void init();
public abstract void start();
public abstract void stop();
public abstract void release();
public virtual Runnable initAsync()
{
Runnable r = new Runnable()
{
@Override
public void Run()
{
init();
}
}
return r;
}
public virtual Runnable startAsync()
{
Runnable r = new Runnable()
{
@Override
public void Run()
{
start();
}
}
return r;
}
public virtual Runnable stopAsync()
{
Runnable r = new Runnable()
{
@Override
public void Run()
{
stop();
}
}
return r;
}
public virtual Runnable releaseAsync()
{
Runnable r = new Runnable()
{
@Override
public void Run()
{
release();
}
}
return r;
}
}
这将为您正在编写的整个 classes 系列提供一个良好的基础,而无需将 Runnable 随处放置。
如果您想在后台线程上强制所有这些 运行,请保护抽象方法。然后将您的执行程序服务放在 parent class 中,而不是返回 Runnable,而是在执行程序服务中启动它。
您的每个 child classes 现在都自动具有所有异步操作,但您只需实施四种方法即可实现。
我正在编写 classes 系列,全部使用相机。 每个class有4个基本方法来初始化、启动、停止或释放相机。
我想运行这些方法在后台线程。但我正在努力寻找一种简单的方法来做到这一点。
我发现的唯一方法是使用定义为
的通用ExecutorService
ExecutorService backgroundThread = Executors.newSingleThreadExecutor();
然后,我必须 将每个方法的代码 包装成这样:
public void start(){
AbstractLight.backgroundThread.execute(new Runnable(){
public void run(){
//write "start method" code here
}
});
}
我想有更聪明的方法可以做到这一点,但我不知道。有人有办法做到这一点吗?
谢谢
您可以使用 Queue
方法调用以及 Router
来确定要调用哪个 class 方法:
public interface Camera {
public void init();
public void start();
public void stop();
public void release();
}
public class Router implements Runnable {
private final EnumMap<CameraType, Camera> cameras = new EnumMap<>(CameraType.class);
private final BlockingQueue<RouterInvocation> queue = new LinkedBlockingQueue<>();
public enum CameraType {
CAMERA1, CAMERA2, //etc
}
private enum CameraMethod {
INIT, START, STOP, RELEASE
}
private class RouterInvocation {
public final Camera camera;
public final CameraMethod cameraMethod;
public RouterInvocation(Camera c, CameraMethod cm) {
this.camera = c;
this.cameraMethod = cm;
}
}
// similar methods for start, stop, release
public void init(CameraType cameraType) {
queue.offer(new RouterInvocation(cameras.get(cameraType), INIT);
}
public void run() {
try {
while(true) {
// wait for next RouterInvocation
RouterInvocation i = queue.take();
if(i.cameraType == INIT) {
i.camera.init();
} else if // same for remaining methods
}
} catch(InterruptedException ex) {
return;
}
}
}
的好处是你只需要提交一个Runnable
(Router
)到ExecutorService
- 然后Router
负责调用合适的方法来自适当的 Camera
实施。
如果您决定要多个线程处理队列,那么您可以在多个 Routers
之间共享队列,或者我的建议是将 ExecutorService
移动到 [=12] =](因此 Router
不再实现 Runnable
而是创建内部 Runnables
来处理队列)。
您可以创建一个包含这些方法的 'async' 版本的摘要 parent class。
从一个抽象的 parent class 开始,然后将它们中的每一个都包装在它们自己的 运行nable 异步版本中。现在,每当您从抽象 parent 继承时,每个都会自动拥有自己的 运行nable。然后您可以将它们放入执行程序或 parent.
中您需要的任何内容public abstract class CameraParent
{
public abstract void init();
public abstract void start();
public abstract void stop();
public abstract void release();
public virtual Runnable initAsync()
{
Runnable r = new Runnable()
{
@Override
public void Run()
{
init();
}
}
return r;
}
public virtual Runnable startAsync()
{
Runnable r = new Runnable()
{
@Override
public void Run()
{
start();
}
}
return r;
}
public virtual Runnable stopAsync()
{
Runnable r = new Runnable()
{
@Override
public void Run()
{
stop();
}
}
return r;
}
public virtual Runnable releaseAsync()
{
Runnable r = new Runnable()
{
@Override
public void Run()
{
release();
}
}
return r;
}
}
这将为您正在编写的整个 classes 系列提供一个良好的基础,而无需将 Runnable 随处放置。
如果您想在后台线程上强制所有这些 运行,请保护抽象方法。然后将您的执行程序服务放在 parent class 中,而不是返回 Runnable,而是在执行程序服务中启动它。
您的每个 child classes 现在都自动具有所有异步操作,但您只需实施四种方法即可实现。