[英]Parallel Read and write application in java
I am developing an application in java where i am using a shared LinkedBlocking Queue and i am creating multiple threads for reading and writing it. 我正在用Java开发一个应用程序,其中我使用一个共享的LinkedBlocking队列,并且正在创建用于读取和写入它的多个线程。 I have created the code as below but i am unable to get the desired result.
我创建了如下代码,但无法获得所需的结果。
For result i am using a shared file which is being written by both the threads (read and write one). 为了获得结果,我使用了一个由两个线程(读写一个线程)写入的共享文件。
Please tell me whats wrong in my code: 请告诉我我的代码有什么问题:
Message Reader.java 消息阅读器
package com.aohandling.messagereader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.aohandling.messagequeue.MessageQueue;
public class MessageReader implements Runnable
{
public static BufferedWriter out;
public static void init()
{
file = new File("AOHandle.txt");
try
{
out = new BufferedWriter(new FileWriter(file, true));
System.out.println("Init ");
}
catch (IOException e)
{
e.printStackTrace();
}
}
static File file = null;
public void run()
{
while (true)
{
try
{
SimpleDateFormat ft = new SimpleDateFormat("E yyyy.MM.dd 'at' hh:mm:ss a zzz");
String s = MessageQueue.getMessageQueue().poll();
if (s != null)
{
out.write("queue - " + MessageQueue.getMessageQueue().poll() + "---" + ft.format(new Date()) + "\n");
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
MessageWriter.java MessageWriter.java
package com.aohandling.writer;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.aohandling.messagequeue.MessageQueue;
import com.aohandling.messagereader.MessageReader;
public class MessageWriter implements Runnable
{
int n;
private int messageSequence;
public MessageWriter(int messageSequence)
{
this.messageSequence = messageSequence;
}
public void run()
{
try
{
SimpleDateFormat ft = new SimpleDateFormat("E yyyy.MM.dd 'at' hh:mm:ss a zzz");
MessageReader.out.append("Writing----AO - " + this.messageSequence + "-----" + ft.format(new Date()) + "\n");
MessageQueue.getMessageQueue().put("AO " + this.messageSequence);
}
catch (IOException | InterruptedException e)
{
e.printStackTrace();
}
}
}
MessageQueue.java MessageQueue.java
package com.aohandling.messagequeue;
import java.util.concurrent.LinkedBlockingQueue;
public class MessageQueue {
private static LinkedBlockingQueue<String> messageQueue = new LinkedBlockingQueue<String>();
public static LinkedBlockingQueue<String> getMessageQueue() {
return MessageQueue.messageQueue;
}
public static void setMessageQueue(LinkedBlockingQueue<String> messageQueue) {
MessageQueue.messageQueue = messageQueue;
}
}
TestAOHandlingRead.java TestAOHandlingRead.java
package com.aohandling.main;
import com.aohandling.messagereader.MessageReader;
import com.aohandling.writer.MessageWriter;
public class TestAOHandlingRead
{
/**
* @param args
*/
public static void main(String[] args)
{
MessageReader.init();
for (int i = 0; i <= 200; i++)
{
Thread readThread = new Thread(new MessageReader());
readThread.start();
}
write();
}
public static void write()
{
for (int i = 0; i <= 20; i++)
{
if (i % 2 == 0)
{
try
{
Thread.sleep(500);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
Thread writeThread = new Thread(new MessageWriter(i));
writeThread.start();
}
}
}
TestAOHandlingWrite.java TestAOHandlingWrite.java
package com.aohandling.main;
import java.util.concurrent.atomic.AtomicInteger;
import com.aohandling.writer.MessageWriter;
public class TestAOHandlingWrite {
int count = 0;
public int getCount()
{
return count;
}
/**
* @param args
*/
public static void main(String[] args) {
// MessageWriter.init();
for (int i=0; i<= 20; i++) {
if (i%2 ==0) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Thread writeThread = new Thread(new MessageWriter(i));
writeThread.start();
}
}
}
I suggest that you will use a FileChannel, since File channels are safe for use by multiple concurrent threads. 我建议您使用FileChannel,因为文件通道可以安全地被多个并发线程使用。 In addition I refactored your code, the channel to your file will be created once, during the the first load of MessageReader class by the class loader.
另外,我重构了您的代码,在类加载器第一次加载MessageReader类的过程中,将创建一次到文件的通道。
public class MessageReader implements Runnable {
private static FileChannel channel;
static {
try {
System.out.println("Init ");
FileOutputStream fileOutputStream = new FileOutputStream(
"AOHandle.txt", true);
FileChannel channel = fileOutputStream.getChannel();
System.out.println("Init ");
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (true) {
FileLock fileLock = null;
try {
SimpleDateFormat ft = new SimpleDateFormat(
"E yyyy.MM.dd 'at' hh:mm:ss a zzz");
String s = MessageQueue.getMessageQueue().poll();
if (s != null) {
String message = "queue - "
+ MessageQueue.getMessageQueue().poll() + "---"
+ ft.format(new Date()) + "\n";
fileLock = channel.lock();
channel.write(ByteBuffer.wrap(message.getBytes()));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fileLock != null) {
fileLock.release();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
The best practice is to open a channel to a file in one place and share him between your threads, since in your code no one closes the file. 最佳实践是在一个位置打开一个文件通道,并在线程之间共享该通道,因为在您的代码中没有人会关闭该文件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.