我正在java中开发一个应用程序,我正在使用共享的LinkedBlocking Queue,我正在创建多个线程来读取和写入它。我已经创建了如下代码,但我无法获得所需的结果。
结果我正在使用一个共享文件,这个文件由两个线程写入(读写一个)。
请告诉我代码中的错误:
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
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
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
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
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();
}
}
}
答案 0 :(得分:0)
我建议您使用FileChannel,因为文件通道可以安全地供多个并发线程使用。另外,我重构了你的代码,在类加载器第一次加载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();
}
}
}
}
}
最佳做法是在一个位置打开一个文件的频道,并在你的线程之间共享,因为在你的代码中没有人关闭文件。