Java多线程任务
我有这样的任务 构建类StringTask,模拟长期计算,此处由字符串串联组成 类构造函数接收要复制的字符串作为参数,以及指示字符串要放大多少次的数字 类必须实现Runnable接口,并且在其run()方法中执行一个字符串的复制,它应该使用+来完成字符串变量(这是长期操作)。+的使用是一个强制性条件 StringTask类的对象被视为可以并行执行的任务 状态任务包括:Java多线程任务,java,multithreading,Java,Multithreading,我有这样的任务 构建类StringTask,模拟长期计算,此处由字符串串联组成 类构造函数接收要复制的字符串作为参数,以及指示字符串要放大多少次的数字 类必须实现Runnable接口,并且在其run()方法中执行一个字符串的复制,它应该使用+来完成字符串变量(这是长期操作)。+的使用是一个强制性条件 StringTask类的对象被视为可以并行执行的任务 状态任务包括: 已创建-已创建但尚未开始执行的任务 正在运行-任务在单独的线程中执行 中止-任务已中断 准备就绪-任务已成功并已准备好结果
- 已创建-已创建但尚未开始执行的任务
- 正在运行-任务在单独的线程中执行
- 中止-任务已中断
- 准备就绪-任务已成功并已准备好结果
-返回 串联公共字符串getResult()
-返回任务的状态public TaskState getState()
-在单独的线程中运行任务public void start()
-挂起任务代码的执行和线程的操作public void abort()
-如果任务完成,则返回true 正常或中断,否则为假public boolean isDone()
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;
}
}