4

我正在编写一个类,它将其他方法中的操作排队到 ConcurrentLinkedQueue 中,然后有一个 process() 方法,该方法只能从处理队列的创建线程调用。这是因为其他方法的操作可以从其他线程调用,但它们的实际操作只能在创建者线程上执行。这类似于 Android 的runOnUiThread,它必须用于在 UI 线程之外运行任何 UI 代码。

我对 process 方法的想法是首先断言创建者线程正在调用它,然后简单地运行队列中的每个事物。我不确定如何将当前线程与存储的线程引用进行比较;我找不到有关是否保证引用相同的文档。我应该使用该equals方法吗?我应该只使用==运营商吗?可以比较 Thread 对象,还是应该比较它们的名称或其他一些数据?

相关的代码将如下所示:(未显示队列逻辑)

public class MultiThreadTasker {
    private Thread creatorThread;

    public MultiThreadTasker() {
        creatorThread = Thread.currentThread();
    }

    public void process() {
        if(Thread.currentThread() != creatorThread) {
            throw new IllegalArgumentException("...");
        }
        // ...
    }

    // ...
}

也欢迎就替代方法提出建议。似乎我正在重新发明一个 Executor,但我没有看到任何类型的 Executor 可以让您手动启动任务的运行而不是它处理自己的线程。

4

2 回答 2

1

如果您只想在当前线程上执行任务,为什么它们要共享一个队列?我将对每个线程都有一个本地队列,只有该线程可以看到/使用。

这就是我会做的。

private static final ThreadLocal<Queue<Runnable>> QUEUE = new ThreadLocal<Queue<Runnable>>() {
    @Override
    protected Queue<Runnable> initialValue() {
        return new LinkedList<Runnable>(); 
    }
};

public static void runLater(Runnable runnable) {
    QUEUE.get().add(runnable);
}

public static void runAll() {
    for (Runnable runnable : QUEUE.get())
        runnable.run();
    QUEUE.get().clear();
}
于 2012-09-10T14:03:07.090 回答
0

如果比较线程不起作用,您可以使用线程本地 UUID(http://docs.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html、http://docs.oracle。 com/javase/1.5.0/docs/api/java/util/UUID.html)来比较调用者。您将在构造函数中填充线程本地字段。

于 2012-09-10T14:00:05.477 回答