[英]Parallel Read and write application in java
我正在用Java開發一個應用程序,其中我使用一個共享的LinkedBlocking隊列,並且正在創建用於讀取和寫入它的多個線程。 我創建了如下代碼,但無法獲得所需的結果。
為了獲得結果,我使用了一個由兩個線程(讀寫一個線程)寫入的共享文件。
請告訴我我的代碼有什么問題:
消息閱讀器
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();
}
}
}
我建議您使用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();
}
}
}
}
}
最佳實踐是在一個位置打開一個文件通道,並在線程之間共享該通道,因為在您的代碼中沒有人會關閉該文件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.