我有像这样的任务
构建类StringTask,模拟长期计算,这里包含字符串的连接.
类构造函数接收要复制的字符串作为参数,以及指示要放大字符串多少次的数字。
类必须实现Runnable接口,并且在它的run()方法中执行字符串复制,应该使用+来执行字符串变量(这是长期操作)。使用+是一个强制性条件。
类StringTask的对象被视为可以并行执行的任务。
状态任务是:
在类StringTask中定义以下方法:
public String getResult ()
-返回连接的结果。public TaskState getState ()
-返回任务的状态public void start ()
-在单独的线程中运行任务
public void abort ()
-暂停任务代码的执行和线程的操作public boolean isDone ()
-如果任务正常完成或中断,则返回true,否则返回false以下程序代码:
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(.)
并得到了这个解决方案,
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();
}
}
但是经过测试,系统给了我这些错误,我不知道如何解决它们。
Behaviour tests results - scoring decrease = -7
时间:我们使用参数'Y‘i 80000调用StringTask构造函数,然后开始任务
需求测试结果-评分下降= -2
案例1:评分下降= -1 -一些变量应该有易失性修饰符。
案例2:评分减少= -1 -您应该检查中断的lub isInterrupted方法中断标志。
如何解决这个问题?我试过了但我不知道。
发布于 2017-04-13 08:31:55
既然我们都不知道实际的失败行为测试,我们所能做的就是猜测。
首先,在StringTask
中,您应该使用private volatile
变量。为了private
,他们应该是封装。它们应该是volatile
,因此多线程的更改将是可见的。有关易失性的进一步讨论,请参见这就是问与答。
关于operations
计数器,您最好使用AtomicInteger
,因为它支持多线程的减量和增量操作。
这些都是精致的领域:
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()
方法。这是一个轻微的不便,我们必须支付非常安全的削减/增量操作。
https://stackoverflow.com/questions/43371471
复制相似问题