我试图在循环内编写一个开关,在 2/5 的情况下,创建了一个匿名类,它捕获循环计数器。这不是直截了当的,因为计数器需要是最终的才能被匿名内部类捕获。解决方案很简单,只需将 afinal int i_
设置为 counter 变量即可。问题是它不起作用(我猜是因为不止一种情况)。这是一段极其简化的代码,与我的真实代码存在相同的问题:
import java.util.concurrent.*;
import java.util.*;
enum E {A,B,C,D,E}
class A {
static void s() {
try {
Thread.sleep(1000);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Semaphore s = new Semaphore(2); // 2 cores
public static void main(String[] _){
LinkedList<E> es = new LinkedList<E>();
es.push(E.A);
es.push(E.D);
es.push(E.B);
es.push(E.C);
es.push(E.E);
es.push(E.C);
es.push(E.C);
es.push(E.E);
es.push(E.A);
es.push(E.A);
f(es);
}
static void f(List<E> es) {
int i = 0;
for (E e : es) {
s.acquireUninterruptibly();
switch(e) {
case A:
final int i_ = i;
new Thread() {
public void run() {
System.out.println("A" + i_); s(); s.release();
}
}.start();
break;
case B:
final int i_ = i;
new Thread() {
public void run() {
System.out.println("B" + i_); s(); s.release();
}
}.start();
break;
case C:
new Thread() {
public void run() {
System.out.println("C"); s(); s.release();
}
}.start();
break;
case D:
new Thread() {
public void run() {
System.out.println("D"); s(); s.release();
}
}.start();
break;
case E:
new Thread() {
public void run() {
System.out.println("E"); s(); s.release();
}
}.start();
break;
default:
break;
}
i++;
}
}
}
它产生线程来完成工作。做什么工作由输入列表中的当前元素决定es
。信号量用于限制当前运行的线程数。
它无法编译,声称i
已经定义:
$ javac A.java && java A
A.java:27: i_ is already defined in main(java.lang.String[])
final int i_ = i;
^
1 error
但是它们在交换机的不同情况下被定义。我认为它会起作用,因为您可以对任何其他类型的块做同样的事情,例如这有效:
class A {
static {
for (int i = 0; i < 1; i++) {
int j = i + 1;
}
for (int i = 0; i < 1; i++) {
int j = i + 1;
}
}
}
为什么它不能与开关一起使用?还有哪些其他方法可以在多个案例中的匿名类中围绕开关捕获计数器?