Java 两个线程写入同一文件
我有多个线程(假设现在有两个),每个线程检索一个HTML页面并将其内容写入一个文件。需要注意的是,每个线程都希望写入相同的输出文件。带有run()方法的类是静态内部类。我希望采用的方法是让每个线程将它想要写入的内容放入一个队列中。然后,在线程完成(或所有线程都完成)后,遍历队列并将内容打印到文件中。我不知道如何实现这一点。同样,实现runnable接口的类是静态的。我并不精通并发,也不一定想做任何花哨的事情。对简单实现有什么建议吗?您可以使用Java 两个线程写入同一文件,java,multithreading,concurrency,Java,Multithreading,Concurrency,我有多个线程(假设现在有两个),每个线程检索一个HTML页面并将其内容写入一个文件。需要注意的是,每个线程都希望写入相同的输出文件。带有run()方法的类是静态内部类。我希望采用的方法是让每个线程将它想要写入的内容放入一个队列中。然后,在线程完成(或所有线程都完成)后,遍历队列并将内容打印到文件中。我不知道如何实现这一点。同样,实现runnable接口的类是静态的。我并不精通并发,也不一定想做任何花哨的事情。对简单实现有什么建议吗?您可以使用java.util.concurrent包中的。每个线
java.util.concurrent
包中的。每个线程都会将其输出放入队列,第三个线程会将元素从队列中取出并写入文件。在用于阻塞队列的API页面上有一个示例,您应该能够将其用于实现。您只需要提供生产
和消费
的实现,就完成了。您可以使用java.util.concurrent
包中的。每个线程都会将其输出放入队列,第三个线程会将元素从队列中取出并写入文件。在用于阻塞队列的API页面上有一个示例,您应该能够将其用于实现。您只需要提供生产
和消费
的实现,就完成了。您也可以使用同步
块。您也可以使用同步
块。根据您的描述,我认为您的生产商应该是这样的:
private static final int CAPACITY = 10; // whatever you like here.
private static Object locker = new Object();
private static Queue<String> queue = new ArrayBlockingQueue<String>(CAPACITY);
private static class ThreadTask implements Runnable {
@Override
public void run() {
// retrieve page
// add result to queue
}
}
private static final int CAPACITY=10;//你喜欢什么都行。
私有静态对象锁定器=新对象();
私有静态队列=新的ArrayBlockingQueue(容量);
私有静态类ThreadTask实现可运行{
@凌驾
公开募捐{
//检索页面
//将结果添加到队列
}
}
当然,您可以在Executor中执行这些ThreadTasks,以便更好地使用系统资源,并且如果您实现生产者-消费者队列系统,您的消费者线程也可以与生产者同时运行。好吧,根据您的描述,我认为生产者应该是这样的:
private static final int CAPACITY = 10; // whatever you like here.
private static Object locker = new Object();
private static Queue<String> queue = new ArrayBlockingQueue<String>(CAPACITY);
private static class ThreadTask implements Runnable {
@Override
public void run() {
// retrieve page
// add result to queue
}
}
private static final int CAPACITY=10;//你喜欢什么都行。
私有静态对象锁定器=新对象();
私有静态队列=新的ArrayBlockingQueue(容量);
私有静态类ThreadTask实现可运行{
@凌驾
公开募捐{
//检索页面
//将结果添加到队列
}
}
当然,您可以在执行器中执行这些线程任务,以便更好地使用系统资源,如果您实现生产者-消费者队列系统,您的消费者线程也可以与生产者同时运行。您可以使用单线程执行器服务。这可用于在生成数据时写入数据(而不必等待)
static final ExecutorService logger = Executors.newSingleThreadExecutor();
static void writeToFile(final FileOutputStream fos, final String text) {
logger.execute(new Runnable() {
public void run() {
try {
fos.write(text.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
您可以使用单线程ExecutorService。这可以用于在生成数据时写入数据(而不必等待)
static final ExecutorService logger = Executors.newSingleThreadExecutor();
static void writeToFile(final FileOutputStream fos, final String text) {
logger.execute(new Runnable() {
public void run() {
try {
fos.write(text.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
该示例显示消费者和生产者类都是非静态的。如果这两个类都是静态的,它会工作吗?因为消费者和生产者都是线程,所以它们不能是静态的。Java中的线程实现可运行接口,并且必须实例化才能执行。当然,您可以重构方法以插入元素into队列,并根据您的程序设计将它们放入静态方法中。该示例显示使用者类和生产者类都是非静态的。如果这两个类都是静态的,它会工作吗?嗯,由于使用者和生产者都是线程,它们不能是静态的。Java中的线程实现可运行接口,并且必须实例化但当然,您可以重构方法,将元素插入队列,并将它们输出到静态方法中,这取决于您的程序设计。同步块是否在运行()中实现Runnable的类的方法?你能给我发一个帖子或给我指出一个例子的方向吗?同步的块在run()中吗实现Runnable的类的方法?你能给我发一篇文章或给我指出一个例子的方向吗?不太确定你是否意识到这已经是生产者-消费者队列系统的一半,你有生产者,你有队列,你现在只需要一个消费者线程。另外,你应该放弃同步,就像ArrayBlocking一样队列(BlockingQueue的一种实现)是为并发访问而设计的。此外,只要没有并发运行的使用者,您可能希望降低容量,否则您的程序将被阻止。我认为容量是您希望写入的总页数。队列大小将等于计算完成时的容量。为了线程安全,您是正确的t、 我编辑过。啊,好吧。如果程序总是获取相同数量的有意义的页面。不太确定你是否意识到这已经是生产者-消费者队列系统的一半,你有生产者,你有队列,你现在只需要一个消费者线程。此外,你应该删除同步,如ArrayBlockingQueue(BlockingQueue的一个实现)是为并发访问而设计的。此外,只要没有并发运行的使用者,您可能希望降低容量,否则您的程序将被阻止。我认为容量是您希望写入的总页数。队列大小将等于计算完成时的容量。为了线程安全,您是正确的t、 我编辑了。啊,好吧。如果程序