java - 如何实现一个可以依次执行或随时停止的作业列表?

标签 java multithreading

我正在开发一个 Swing 应用程序,它基本上收集列表中的作业(任务)并依次执行它们。我有两个按钮:“开始”和“停止”。 “开始”应该开始执行,当作业完成时,应该可以单击“停止”来停止执行。

我想我必须使用多线程才能随时中断执行。但我不太熟悉多线程,我认为我缺少正确的方法。

到目前为止,我有一个工作界面:

public interface Job {

    void start();

    void interrupt();

}

这样就可以实现类来扩展 Thread 。但是,如果我然后开始执行列表,启动将立即返回,并且下一个作业将开始,尽管上一个作业尚未完成。如果我用 .join() 等待执行我无法中断工作。

目前,工作的处理方式如下( jobs 的类型为 List<Job> ):

public void startWork() {
    while (!jobs.isEmpty()) {
        jobs.get(0).start();
        jobs.remove(0);
    }
}

你对我的问题有什么想法吗?我真的被困住了。

更新

感谢您的回答!

我现在可以开始工作了。我的JobManager现在看起来像这样:

public final class JobManager {

    /**
     * The list of jobs.
     */
    private List<Job> jobs = new ArrayList<Job>();

    /**
     * The worker thread.
     */
    private ExecutorService worker = Executors.newSingleThreadExecutor();

    /**
     * Works off the job list.
     */
    public void startWork() {
        worker.execute(new Runnable() {

            @Override
            public void run() {
                while (!jobs.isEmpty()) {
                    jobs.get(0).start();
                    jobs.remove(0);
                }
            }

        });
    }

    /**
     * Stops the work off.
     */
    public void stopWork() {
        worker.shutdownNow();
    }

}

但是 shutdownNow() 有问题。在工作中,我必须定期检查线程是否被中断。是否可以完全杀死一个线程? 我认为这些定期检查将是很大的开销,而且我始终必须确保作业确实检查中断。

最佳答案

如果我理解正确的话,你想一一运行你的作业 - 换句话说,你不需要你的作业是一个线程/可运行的。

相反,执行作业的进程应该在线程中,以便您的 Swing 应用程序可以在需要时启动/停止。

如果上述假设是正确的..

将作业定义为

interface Job{
    void start();
    boolean isCompleted();
}

实际工作为

class JobInstance implements Job {

String name;
boolean isCompleted;

public JobInstance(String name) {
    this.name  = name;
}


/**
 * @return the isCompleted
 */
public boolean isCompleted() {
    return isCompleted;
}


@Override
public void start() {

    System.out.println("Job "+this.name+" Started");
    try {
        Thread.sleep(10000);
        System.out.println("Job "+this.name+" Completed");
        isCompleted = true;
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        System.out.println("Interuppted.. Mark me finish / dont remove from List");
    }


}

}

如果没有触发中断,该作业将以正常方式工作并标记为已完成。 使正在执行此作业的类可运行为

public class Process implements Runnable{

List<Job> jobLists;

public Process(List<Job> lists) {
    this.jobLists = lists;
}

@Override
public void run() {
    System.out.println(Thread.currentThread().getName());
    while(!jobLists.isEmpty()){
        Job job = jobLists.get(0);
        job.start();
        if (job.isCompleted()){
            jobLists.remove(0);
        }else{
            System.out.println("Interrup issuesed");
            return;
        }

    }
}   

}

您可以使用以下方法验证这一点...

JobInstance job1 = new JobInstance("A");
    JobInstance job2 = new JobInstance("B");
    ArrayList<Job> jobLists = new ArrayList<>();
    jobLists.add(job1);
    jobLists.add(job2);
    Process process = new Process(jobLists);
    System.out.println(Thread.currentThread().getName());
    Thread thread = new Thread(process);
    thread.start();

    try {
        Thread.sleep(15000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    thread.interrupt();

如果您需要任何信息,请告诉我..

注意**,我认为使用基本线程进行演示,有很多方法可以使用执行器等来实现相同的目的。

更新

如果您的任务/进程没有阻塞,那么发出中断不会停止线程。检查 Thread.interrupt 文档/规范以获取更多详细信息。

如果您打算停止非阻塞任务/作业,请使用 executorService 查找以下示例

作业管理器 - 根据您的规范,仅启动一个线程。

public final class JobManager {


public JobManager(List<Runnable> jobs){
    this.jobs = jobs;
}
/**
 * The list of jobs.
 */
private  List<Runnable> jobs = new ArrayList<Runnable>();

/**
 * The worker thread.
 */
private final ExecutorService worker = Executors.newSingleThreadExecutor();

/**
 * Works off the job list.
 */
public void startWork() {

    for (Iterator<Runnable> iterator = jobs.iterator(); iterator.hasNext();) {
        Runnable task =  iterator.next();
        worker.execute(task);
    }
}

/**
 * Stops the work off.
 */
public void stopWork() {
    worker.shutdownNow();
    jobs.clear();
}
}

您的任务...在 run 方法中实现该流程。

class Task implements Runnable{
String name;


public Task(String name) {
    super();
    this.name = name;
}


@Override
public void run() {
    System.out.println("Job "+this.name+" Started");
    long k=1;
    for(int i=0;i<=Integer.MAX_VALUE/1.5;i++){
        k = k +k;
    }

    System.out.println("Job  "+this.name+ "Completed");
}

 }

测试一下

public static void main(String args[]){
Task job1 = new Task("A");
Task job2 = new Task("B");
ArrayList<Runnable> jobLists = new ArrayList<>();
jobLists.add(job1);
jobLists.add(job2);
JobManager manager = new JobManager(jobLists);
manager.startWork();
try {
    Thread.sleep(150);
} catch (InterruptedException e) {
    e.printStackTrace();
}
manager.stopWork();
System.out.println("Issued Stop");

}

关于java - 如何实现一个可以依次执行或随时停止的作业列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22481878/

相关文章:

MySql 连接丢失 Delphi

java - 我需要同步对中断方法的调用吗?

java - Fork 和 Join 特性 jdk7 线程数

java - Mongo的自增功能无法设置Long为_id?

java - 为什么在 Enum hashCode() 中引用 Object hashCode() 实现,而不是 ordinal() 函数?

java - 导入数字的值为 123,45,但 123.45 使用 JAVA 存储在数据库中

java - 将尾随 0 添加到我的 0.1、0.2 值,但不添加到我的 0.25 值

java - 在窗口管理器中膨胀类时出错

c - Windows 中的用户空间 APC 队列长度

java - Nodejs 在单线程环境中进行许多剩余调用