2013-10-17 2 views
0

나는 자바에서 공유 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(); 
    } 
    } 
} 

에게

메시지 Reader.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

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

원하는 결과는 두 스레드가 쓰고있는 txt 파일에서 병렬 읽기 및 쓰기 작업을보고 싶습니다. 잘못된 점은 단일 메인에서이 응용 프로그램을 실행하는 방법과 작성자 스레드가 텍스트 파일을 쓸 수 없다는 것입니다. – Scientist

답변

0

내가 파일 채널은 복수의 병행 thread로 안전하게 사용할 수 있기 때문에 당신이하는되는 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(); 
      } 
     } 
    } 
} 
} 

가장 좋은 방법은 아무도 파일을 닫없는 코드에 있기 때문에, 한 곳에서 파일에 대한 채널을 열고 스레드간에 그를 공유하는 것입니다.