我有以下方法,每当我单击一个按钮时都会调用此方法,结果是在按下按钮时一次又一次地启动新线程,这导致线程的多次初始化,但是我只希望一个线程应该得到执行,我怎么能做到这一点。
private void scheduleMessages() {
new Thread(new Runnable() {
@Override
public void run() {
//Some operations
}
}).start();
}
注意:这是一个很小的方法,我不想创建一个单独的类,只是为了使其成为单例,因此不使用单例模式的解决方案将不胜感激。
答案 0 :(得分:1)
如果无法通过实例检查isActive()
,则应创建一个信号量变量-一个布尔值,在启动线程时将其设置为true
,在启动线程时将其设置为false
完成。
private void scheduleMessages() {
if (!taskRunning){
new Thread(new Runnable() {
@Override
public void run() {
taskRunning = true;
//Some operations
taskRunning = false;
}
}).start();
}
}
答案 1 :(得分:0)
将该线程设为后台线程-也许在第一次按下该按钮时将其初始化。
让该线程侦听队列-并对该队列中的消息进行操作。
每当再次按下该按钮时,就将新消息放入队列。
答案 2 :(得分:0)
如果需要在特定数量的线程上执行每个请求,则可以使用线程池,让执行者管理队列。
private ExecutorService services;
private final static int POOL_SIZE = 1;
public MessagesService(){
services = Executors.newFixedThreadPool(POOL_SIZE);
}
public void scheduleMessages(Runnable r){
services.submit(r);
}
如果您调用addCall
x次,则x线程将在最后执行,但使用的线程数绝不能超过池中可用的线程数。这里有1个线程。
对于仅接受一个请求的系统,您可以使用相同的方法,但要检查单个线程执行器返回的Future
。这样,您可以检查服务的状态。
private ExecutorService services;
private Future<?> lastCall;
public MessagesService() {
services = Executors.newSingleThreadExecutor();
lastCall = null;
}
public synchronized void scheduleMessages(Runnable r) {
if(!isScheduled()){
lastCall = services.submit(r);
}
}
public boolean isScheduled(){
return lastCall != null && !lastCall.isDone();
}
这样,Runnable
不需要更新标志,从而提供了可重用的解决方案。
这里是Runnable
的示例,用于测试这些代码:
new Runnable() {
System.out.println("Running");
try {
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
}