Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java多线程任务_Java_Multithreading - Fatal编程技术网

Java多线程任务

Java多线程任务,java,multithreading,Java,Multithreading,我有这样的任务 构建类StringTask,模拟长期计算,此处由字符串串联组成 类构造函数接收要复制的字符串作为参数,以及指示字符串要放大多少次的数字 类必须实现Runnable接口,并且在其run()方法中执行一个字符串的复制,它应该使用+来完成字符串变量(这是长期操作)。+的使用是一个强制性条件 StringTask类的对象被视为可以并行执行的任务 状态任务包括: 已创建-已创建但尚未开始执行的任务 正在运行-任务在单独的线程中执行 中止-任务已中断 准备就绪-任务已成功并已准备好结果

我有这样的任务

构建类StringTask,模拟长期计算,此处由字符串串联组成

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

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

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

状态任务包括:

  • 已创建-已创建但尚未开始执行的任务
  • 正在运行-任务在单独的线程中执行
  • 中止-任务已中断
  • 准备就绪-任务已成功并已准备好结果
在StringTask类中定义以下方法:

  • 公共字符串getResult()
    -返回 串联
  • public TaskState getState()
    -返回任务的状态
  • public void start()
    -在单独的线程中运行任务

    public void abort()
    -挂起任务代码的执行和线程的操作

  • public boolean isDone()
    -如果任务完成,则返回true 正常或中断,否则为假

以下程序代码:

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());
    }
}
但是经过测试,系统给了我这些错误,我不知道该怎么解决

Behaviour tests results - scoring decrease = -7
当:我们使用参数“Y”i 80000调用StringTask构造函数,然后我们开始执行任务

  • abort方法应该停止任务的执行 (abort()方法不终止线程) 得分下降=-7


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

案例1:得分下降=-1 -有些变量应该有volatile修饰符

案例2:得分下降=-1 -您应该通过中断润滑isInterrupted方法检查中断标志


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

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

首先,在
StringTask
中,应该使用
private volatile
变量。为了安全起见,它们应该是私有的。它们应该是易变的,因此多线程更改将可见。有关volatile的进一步讨论,请参阅

关于
操作
计数器,最好使用它,因为它支持多线程递减和递增操作

因此,这些是细化字段:

private volatile TaskState myState;
private volatile String text;
private volatile String resultText;
private final AtomicInteger operations = new AtomicInteger(0);
这需要对第二个构造函数进行一个小的更改:

public StringTask(String a, int i) {
    this();
    text = a;
    operations.set(i); // this is the change
    resultText = "";
}
另外,
abort()
方法需要在
run()
中停止执行。我会像这样做,
abort()
更新
myState
标志,并且
run()
不断读取该标志:

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()
方法。这是一个轻微的不便,我们必须为非常安全的递减/递增操作付费。

您需要发布MCVE
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;
    }
}