首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java多线程任务

Java多线程任务
EN

Stack Overflow用户
提问于 2017-04-12 13:49:27
回答 1查看 545关注 0票数 2

我有像这样的任务

构建类StringTask,模拟长期计算,这里包含字符串的连接.

类构造函数接收要复制的字符串作为参数,以及指示要放大字符串多少次的数字。

类必须实现Runnable接口,并且在它的run()方法中执行字符串复制,应该使用+来执行字符串变量(这是长期操作)。使用+是一个强制性条件。

类StringTask的对象被视为可以并行执行的任务。

状态任务是:

  • 已创建的任务,但尚未开始执行,
  • 运行--任务在单独的线程中执行。
  • 中止-任务已被中断。
  • 准备--这项任务是成功的,并且是现成的结果。

在类StringTask中定义以下方法:

  • public String getResult () -返回连接的结果。
  • public TaskState getState () -返回任务的状态
  • public void start () -在单独的线程中运行任务 public void abort () -暂停任务代码的执行和线程的操作
  • public boolean isDone () -如果任务正常完成或中断,则返回true,否则返回false

以下程序代码:

代码语言:javascript
运行
复制
public class Main {

    public static void main(String[] args) throws InterruptedException {
        StringTask task = new StringTask("A", 70000);
        System.out.println("Task " + task.getState());
        task.start();
        if (args.length > 0 && args[0].equals("abort")) { 
        /*
            <- here add the code interrupting the task after a second 
            and run it in a separate thread
        */
        }
        while (!task.isDone()) {
            Thread.sleep(500);
            switch(task.getState()) {
                case RUNNING: System.out.print("R."); break;
                case ABORTED: System.out.println(" ... aborted."); break;
                case READY: System.out.println(" ... ready."); break;
                default: System.out.println("uknown state");
            }
        }
        System.out.println("Task " + task.getState());
        System.out.println(task.getResult().length());
    }
}

在没有任何参数的情况下运行时,应该使用如下内容:

任务创造了R ..。准备好的。任务准备就绪70000并使用参数中止运行,放置如下所示:

任务创造了R . .。流产了。任务中止31700注1. Main.java文件只能在标记为/* <- */ Note 2的位置修改。不要使用方法System.exit(.)

并得到了这个解决方案,

代码语言:javascript
运行
复制
package zad2;

/**
 * Created by szhyhalo on 09.04.17.
 */
public class StringTask implements Runnable {


    public enum TaskState {
        CREATED, RUNNING, ABORTED, READY
    }

    public boolean isDone = false;
    public TaskState myState;
    public String text;
    public String resultText;
    public Thread myThread;
    public int operations;

    public StringTask() {
        myState = TaskState.CREATED;
    }

    public StringTask(String a, int i) {
        this();
        text = a;
        operations = i;
        resultText = "";
    }

    public boolean isDone() {
        if (myState == TaskState.READY || myState == TaskState.ABORTED) return true;
        return false;
    }

    public void abort() {
        while (operations != 0) {
            resultText += text;
            operations--;
        }
    }

    @Override
    public void run() {
        while (operations != 0) {
            resultText += text;
            operations--;
        }
        myState = TaskState.READY;
    }

    public TaskState getState() {
        return myState;

    }

    public String getResult() {
        return resultText;
    }

    public void start() {
        myThread = new Thread(this);
        myState = TaskState.RUNNING;
        myThread.start();


    }
}

但是经过测试,系统给了我这些错误,我不知道如何解决它们。

代码语言:javascript
运行
复制
Behaviour tests results - scoring decrease = -7

时间:我们使用参数'Y‘i 80000调用StringTask构造函数,然后开始任务

  • 中止方法应该停止任务的执行( abort()方法不终止线程)记分减少= -7

需求测试结果-评分下降= -2

案例1:评分下降= -1 -一些变量应该有易失性修饰符。

案例2:评分减少= -1 -您应该检查中断的lub isInterrupted方法中断标志。

如何解决这个问题?我试过了但我不知道。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-04-13 08:31:55

既然我们都不知道实际的失败行为测试,我们所能做的就是猜测。

首先,在StringTask中,您应该使用private volatile变量。为了private,他们应该是封装。它们应该是volatile,因此多线程的更改将是可见的。有关易失性的进一步讨论,请参见这就是问与答

关于operations计数器,您最好使用AtomicInteger,因为它支持多线程的减量和增量操作。

这些都是精致的领域:

代码语言:javascript
运行
复制
private volatile TaskState myState;
private volatile String text;
private volatile String resultText;
private final AtomicInteger operations = new AtomicInteger(0);

这需要对第二个构造函数进行小的更改:

代码语言:javascript
运行
复制
public StringTask(String a, int i) {
    this();
    text = a;
    operations.set(i); // this is the change
    resultText = "";
}

另外,abort()方法需要在run()中停止执行。我会这样做,比如,abort()更新myState标志,run()继续读取该标志:

代码语言:javascript
运行
复制
public void abort() {
    myState = TaskState.ABORTED;
}

@Override
public void run() {
    myState = TaskState.RUNNING;
    while (operations.get() != 0 && myState != TaskState.ABORTED) {
        resultText += text;
        operations.decrementAndGet();
    }
    if (myState != TaskState.ABORTED) {
        myState = TaskState.READY;
    }
}

注意,上面的这些方法使用了get()AtomicInteger()decrementAndGet()方法。这是一个轻微的不便,我们必须支付非常安全的削减/增量操作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43371471

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档