Java 如何在已定义的线程(池)上运行类的方法?
我正在写一个系列的课程,都是用相机写的每个类有4个基本方法初始化、启动、停止或释放相机 我想在后台线程中运行这些方法。但我正在努力找到一个简单的方法来做到这一点 我发现的唯一方法是使用一个定义为Java 如何在已定义的线程(池)上运行类的方法?,java,android,multithreading,threadpool,Java,Android,Multithreading,Threadpool,我正在写一个系列的课程,都是用相机写的每个类有4个基本方法初始化、启动、停止或释放相机 我想在后台线程中运行这些方法。但我正在努力找到一个简单的方法来做到这一点 我发现的唯一方法是使用一个定义为 ExecutorService backgroundThread = Executors.newSingleThreadExecutor(); 然后,我必须将每个方法的代码围绕如下内容进行包装: public void start(){ AbstractLight.backgroundThre
ExecutorService backgroundThread = Executors.newSingleThreadExecutor();
然后,我必须将每个方法的代码围绕如下内容进行包装:
public void start(){
AbstractLight.backgroundThread.execute(new Runnable(){
public void run(){
//write "start method" code here
}
});
}
我想有一个更聪明的方法,但我不知道。有人会耍花招吗
谢谢您可以使用方法调用的
队列以及路由器来确定要调用哪个类的方法:
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;
}
}
}
公共接口摄像机{
公共void init();
公共无效开始();
公共停车位();
公开无效释放();
}
公共类路由器实现可运行{
私有最终EnumMap摄影机=新EnumMap(CameraType.class);
private final BlockingQueue=新建LinkedBlockingQueue();
公共枚举摄影机类型{
摄像机1,摄像机2,等等
}
私有枚举摄像方法{
初始化、启动、停止、释放
}
私人职业{
公共最终摄像机;
公共最终摄影师法;
公共路线职业(摄像机c、摄像法cm){
这个相机=c;
本.摄像方法=厘米;
}
}
//启动、停止、释放的类似方法
公共void init(CameraType CameraType){
queue.offer(新路由职业(cameras.get(cameraType),INIT);
}
公开募捐{
试一试{
while(true){
//等待下一个假期
RouterInvocation i=queue.take();
if(i.cameraType==INIT){
i、 camera.init();
}else if//其余方法相同
}
}捕获(中断异常例外){
回来
}
}
}
这样做的好处是,您只需将一个Runnable
(Router
)提交给ExecutorService
)-然后Router
负责从相应的摄像机
实现中调用相应的方法
如果您决定需要多个线程处理队列,那么您可以在多个路由器
之间共享队列,或者我的建议是将ExecutorService
移动到路由器
(因此Router
不再实现Runnable
,而是创建内部Runnables
来处理队列)。您可以使用方法调用的队列以及Router
来确定要调用哪个类的方法:
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;
}
}
}
公共接口摄像机{
公共void init();
公共无效开始();
公共停车位();
公开无效释放();
}
公共类路由器实现可运行{
私有最终EnumMap摄影机=新EnumMap(CameraType.class);
private final BlockingQueue=新建LinkedBlockingQueue();
公共枚举摄影机类型{
摄像机1,摄像机2,等等
}
私有枚举摄像方法{
初始化、启动、停止、释放
}
私人职业{
公共最终摄像机;
公共最终摄影师法;
公共路线职业(摄像机c、摄像法cm){
这个相机=c;
本.摄像方法=厘米;
}
}
//启动、停止、释放的类似方法
公共void init(CameraType CameraType){
queue.offer(新路由职业(cameras.get(cameraType),INIT);
}
公开募捐{
试一试{
while(true){
//等待下一个假期
RouterInvocation i=queue.take();
if(i.cameraType==INIT){
i、 camera.init();
}else if//其余方法相同
}
}捕获(中断异常例外){
回来
}
}
}
这样做的好处是,您只需将一个Runnable
(Router
)提交给ExecutorService
)-然后Router
负责从相应的摄像机
实现中调用相应的方法
如果您决定需要多个线程处理队列,那么您可以在多个路由器
之间共享队列,或者我的建议是将ExecutorService
移动到路由器
(因此Router
不再实现Runnable
,而是创建内部Runnables
来处理队列)。您可以创建一个包含这些方法的“异步”版本的抽象父类
从一个抽象父类开始,并将它们包装在各自的可运行异步版本中。现在,每当您从抽象父类继承时,每个类都将自动拥有自己的可运行。然后,您可以将它们放入执行器中,或者从父类中获取所需的任何内容
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;
}
}
这将为您正在编写的整个类家族提供一个良好的基础,而无需到处放置可运行程序
如果要强制所有这些在后台线程上运行,请保护抽象方法。然后将executor服务放在父类中,而不是返回Runnable,而是在executor服务中启动它
现在,您的每个子类都自动执行所有异步操作,但您只需实现这四个方法即可。您可以创建一个抽象父类,其中包含这些方法的“异步”版本
从一个抽象父类开始,并将它们包装在各自的可运行异步版本中。现在,每当您从抽象父类继承时,每个类都将自动拥有自己的可运行。然后,您可以将它们放入执行器中,或者从父类中获取所需的任何内容
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;
}
}
这将为你的整个班级打下良好的基础