当前位置: 首页 > 知识库问答 >
问题:

Java将对象与Executor中的每个线程相关联

牧甫
2023-03-14

我有一堆运行程序,我想通过线程池来执行。然而,每个运行程序也会将一些结果写入一些文件。所以现在,运行程序的界面很简单:

class MyRunnable implements Runnable {
    ...
    MyRunnable(BufferedWriter writer, Task t) {
       this.writer = writer;
       this.task = t;
    }

    public void run() {
       ...
       this.writer.write(SOME_DATA);
    }
}

然而,我想要的是将一个BufferedWriter(换句话说,一个输出文件)与Executor池中的每个线程相关联。但是,我正在调用。使用执行器服务执行功能,如下所示:

BufferedWriter[] writers = initialize to 20 BufferedWriters;
ExecutorService executor = Executors.newFixedThreadPool(20);
for (Task t : tasks) {
    MyRunnable runnable = new MyRunnable(WHAT SHOULD GO HERE?, t)
    executor.execute(runnable);
}

我不知道执行器将分配哪个线程来运行给定的任务,所以我不知道应该向runnable提供哪个BufferedWriter。如何确保ExecutorService管理的每个线程都与一个对象(在本例中为BufferedWriter)关联?

共有2个答案

麻鹏鹍
2023-03-14

...我想要的是将一个BufferedWriter(换句话说,一个输出文件)与执行器池中的每个线程相关联...

@djechlin关于ThreadLocal的回答很好,但问题是,当线程完成运行最后一个任务时,您无法访问BufferedWriterclose()它们。

另一个答案可以在这里看到:

具有持久工作实例的线程池

在这篇文章中,我建议创建你自己的任务的BlockingQueue,每个线程分叉一个任务,让这些线程从你的队列中获取任务。所以线程运行方法类似于:

private final BlockingQueue<MyRunnable> queue = new ArrayBlockingQueue<>();
// if you want to shutdown your threads with a boolean
private volatile boolean shutdown;
...

// threads running in the `ExecutorService` will be doing this run() method
public void run() {
    // this allows them to maintain state, in this case your writer
    BufferedWriter writer = ...;
    while (!shutdown && !Thread.currentThread.isInterrupted()) {
        // they get their tasks from your own queue
        MyRunnable runnable = queue.take();
        // if you are using a poison pill but you'll have to add X of them
        if (runnable == STOP_OBJECT) {
            break;
        }
        runnable.run();
    }
    writer.close();
}

在这里,告诉线程何时完成有点棘手。您可以向队列中添加“毒药丸”对象,但必须向队列中添加与正在运行的线程数量相同的对象。

唐俊爽
2023-03-14

有一个名为ThreadLocal的类。

例如。

ThreadLocal<Type> t = new ThreadLocal<>() {
    @Override protected Type initialValue() {
        return new Type(Thread.currentThread.getName());
}

每当新线程尝试访问t时,这将延迟初始化类型。

我上一次使用这个类只是在一个类中计算出某台机器最擅长运行多少线程。(答案通常是“内核的数量”,但我想确保虚拟内核驱动了这个数量,而不是物理内核)。所以我写了一个任务,其中每个线程只发送了一个AtomicInteger计数器。但是所有线程都在争夺一个计数器,这在处理线程争用时产生了大量开销,所以我创建了一个threadlocal计数器,这样线程就可以在不受其他线程干扰的情况下发送自己的计数器的垃圾邮件。

它的用例有些模糊,因为大多数好的多线程设计都会避免这种情况,但当然也有这样的时候。

 类似资料:
  • 问题内容: 我想在C中分配一些内存,并使其与Java对象实例相关联,如下所示: 然后在Java对象被垃圾回收时释放内存-我可以通过从Java对象的 finalize() 方法调用JNI函数来实现。 问题是,如何将C指针与java对象关联?在对象中保留一个 长 字段并将指针强制转换为 long ?有没有更好的办法? 问题答案: 通常,如果要将指针从C转移到Java,建议使用,以便在平台为64位的情况

  • 在学习基本的线程管理时,我发现很难理解书中的这些行(粗体)。 一旦您启动了线程,您需要明确地决定是等待它完成(通过与它连接--参见第2.1.2)还是让它自己运行(通过分离它--参见第2.1.3)。如果在std::Thread对象被销毁之前没有做出决定,那么程序将被终止(std::Thread析构函数调用std::Terminate())。因此,即使存在异常,也必须确保线程正确连接或分离。有关处理此

  • 我正在尝试理解线程、处理程序、循环器。我看过视频,其中家伙说以下每个Android线程都与Looper(消息队列)相关联。所以这意味着当我创建Thread类实例时,它隐含地创建了它自己的连接到此线程的looper?还是这是错误的?Handler连接到创建它的线程,如果处理程序将发布消息的每个线程中没有looper?另一个问题是关于HandlerThread的。使用这个类的目的是什么,利弊是什么。希

  • 问题内容: class MyObject { 我正在使用静态整数获取此输出: 对象1的instanceCounter的值:5 MyObject的instanceCounter值:5 对象1的计数器值:1 对象2的计数器值:2 对象3的计数器值:3 对象4的计数器值:4 对象5的计数器值:5 但其显示 对象1的instanceCounter的值:5 MyObject的instanceCounter值

  • 我已经面临这个问题很多天了,请帮我解决。我正在使用线程同步实现生产者-消费者示例。我在这个传统节目中做了一些调整。我没有只使用一个队列对象,而是使用了两个队列对象。但程序不起作用。。(PS-我知道我可以通过只使用队列的一个对象来让这个程序工作,但如果我想使用两个队列对象呢??) 类队列{ } 类生产者实现Runnable{ } 类消费者实现可运行{ } 公共类测试队列{ }

  • 问题内容: 我正在使用Node.js和Socket.io进行复杂的游戏,需要将socket.io对象存储在内存中,还需要为套接字对象分配属性(例如,名称,来​​自套接字的某些操作的计数器等) 在下面的代码中,我展示了一个我要实现的示例。我将所有套接字存储在一个数组中,并且还有另一个数组用于存储套接字的name属性。在任何时候,如果我收到名称的请求,都可以从内存中的数组中选择名称。 但是现在我的用户