对标题措辞奇怪的表示歉意,但是我在测试中遇到了一个有趣的并发问题。以下是相关代码:
import java.io.File;
import java.util.Scanner;
import java.io.IOException;
public class ImportData {
public static void main(String[] args) throws Exception {
File f = new File("C:\\Users\\User\\eclipse-workspace\\Coursework\\src");
File[] fileList = f.listFiles();
Scanner input = new Scanner(System.in);
System.out.println("Enter month: ");
int month = input.nextInt();
System.out.println("Enter Police region: ");
String region = input.next();
input.close();
try {
File af = new File(fileList[month].getCanonicalPath());
System.out.println(af.toString());
for(int i = 0; i<fileList.length;i++) {
String fname=fileList[month].getCanonicalPath();
if (fname.contains(region)) {
//deal with file;
}
else {
//write error message
}
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
问题是public class CancelableOperation {
boolean canceled;
boolean started;
public void start() {
if (!canceled) {
started = true;
// Kick off actual operation on another thread
}
}
public void cancel() {
if (!started) {
canceled = true;
} else {
// Attempt to cancel the other operation
}
}
}
@Test
public void test() {
CancelableOperation op = new CancelableOperation();
op.start();
while (!op.started) {
Thread.sleep(5);
}
op.cancel();
}
在cancel()
之后,但在新线程开始实际操作之前被调用。实际上,“实际”启动该操作大约需要3毫秒,但这对于在我的测试中调用started
来说是足够的时间。我当然可以在测试中放入一个小的true
(在我们确定cancel()
为真之后)以等待操作开始,但是我想改为更改代码处理这种情况。
显然,在辅助线程上启动操作是问题的根源,但是,由于该操作是一个漫长且同步的过程,因此将其移到该线程上是不可行的。任何帮助将不胜感激!
答案 0 :(得分:0)
您可以使用CyclicBarrier
CyclicBarrier。 CyclicBarrier是一个同步器,它允许一组 线程等待彼此到达一个共同的执行点 称为障碍。 CyclicBarriers用于我们拥有的程序中 一定数量的线程,必须互相等待才能到达一个 继续执行之前的共同点。
因此该代码将帮助您:
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
class CancelableOperation {
boolean canceled;
boolean started;
public static final CyclicBarrier gate = new CyclicBarrier(2);
public CancelableOperation() {
gate.reset();
}
public void start() {
if (!canceled) {
System.out.println("started");
started = true;
try {
gate.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
// Kick off actual operation on another thread
}
}
public void cancel() {
try {
gate.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
if (!started) {
System.out.println("canceled");
canceled = true;
} else {
// Attempt to cancel the other operation
}
}
}
public class Test {
public static void main(String[] args) {
CancelableOperation op = new CancelableOperation();
new Thread(op::start).start();
new Thread(op::cancel).start();
}
}
因此,如果cancel()
到达gate.await();
,它将锁定直到start()
到达另一个线程