多线程&文件阅读

时间:2013-12-29 07:40:43

标签: java multithreading

我想创建应用程序,其中有两个线程一个线程读取char数据另一个线程将其打印到控制台我有以下代码到interThreadCommunication(假设文件有数据,如s t a c k o v e r f l o w)我生成的输出如下:

From echo int  115 char value s
From echo int  116 char value t
From echo int  97 char value a
From echo int  99 char value c
From echo int  107 char value k
From echo int  111 char value o
From echo int  118 char value v
From echo int  101 char value e
From echo int  114 char value r
From echo int  102 char value f
From echo int  108 char value l
From echo int  111 char value o
From echo int  119 char value w
From echo int  10 char value 

代码:

import java.io.*;
class store
{
    int  i;
    public int get()
    {
        return i;
    }
    public void set(int i)
    {
        this.i=i;
    }
}
public class Main
{
    public static void main(String a[])
    {
        store s=new store();
        Thread th=new Thread(new read(s));
        Thread pr=new Thread(new echo(s));
        th.start();
        pr.start();             
    }   
}
class echo implements Runnable
{
    store st;
    public echo(store s)
    {
        st=s;
    }
    public void run()
    {       
        while(true)
        {
            int t=st.get();         
            if(t==-1)
                break;              
            if(t!=32)
            {
System.out.println("From echo int  "+t+" char value "+(char)st.get());  
            }
            st.set(0);
            try
            {
                //Thread.sleep(200);
                while(true)
                {
                    this.wait();
                    if(st.get()!=0)
                        break;

                }
            }
            catch(Exception r)
            {
            }
        }
    }   
}
class read implements Runnable
{
    FileReader fr=null;
    int r;
    store st;
    public read(store s)
    {
        st=s;
    }
    public void run()
    {
        try
        {
            fr=new FileReader("data.txt");
            while(true)
            {
                int r=fr.read();
                st.set(r);
                while(st.get()==0)
                {                   
                    this.wait();
                }   
                if(r==-1)
                    break;              
                try
                {
                    Thread.sleep(200);
                }
                catch(Exception re)
                {
                }
            }   
            st.set(-1);         
        }   
        catch(Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            try
            {   
                fr.close();
            }
            catch(Exception e)
            {
                e.printStackTrace();    
            }
        }               
    }
}

如果我从类read和amp;中删除sleep()方法回声然后我得到了

From echo int  0 char value 
From echo int  0 char value 
From echo int  0 char value 
.
.
.

我正在使用wait()方法来处理另一个线程。我正在以正确的方式进行,或者 interThreadCommunication

还有其他方法

3 个答案:

答案 0 :(得分:2)

程序包java.util.concurrent包含现成的BlockingQueueTransferQueue,它们就是为此而设计的。以下是使用ArrayBlockingQueue编写程序的示例:

import java.io.*;
import java.util.concurrent.*;

public class Main {
    public static void main(String args[]) {
        BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(100);
        Thread th = new Thread(new Read(queue));
        Thread pr = new Thread(new Echo(queue));
        th.start();
        pr.start();
    }
}

class Read implements Runnable {
    private final BlockingQueue<Integer> queue;

    public Read(BlockingQueue<Integer> queue) {
        this.queue = queue;
    }

    public void run() {
        try (FileReader fr = new FileReader("data.txt")) {
            for (;;) {
                int c = fr.read();
                queue.put(c);
                if (c == -1) break;
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

class Echo implements Runnable {
    private final BlockingQueue<Integer> queue;

    public Echo(BlockingQueue<Integer> queue) {
        this.queue = queue;
    }

    public void run() {
        try {
            for (;;) {
                int c = queue.take();
                if (c == -1) break;
                System.out.println("From echo int " + c + " char value " + (char)c);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

答案 1 :(得分:-1)

您正在以错误的方式使用wait()方法。

此方法在超类Object中声明,其目的是暂停当前线程,直到另一个线程调用方法notify()为止,这也是重要的一点。 Object

wait-and-notify机制实现了一种线程同步,其中一个线程能够在继续执行之前等待某个条件成为现实。

  • 详细了解Javas类Object的API文档 here

  • 因为你只能在一个中使用Object.wait()和Object.Notify() 我也建议看看here

顺便说一下,我不认为你的代码在运行时会起作用,因为你在调用this.wait()而不是在一个受保护的块中。这是synchronized关键字声明的一个块,例如如下所示:

synchronized (this) {

    // ...

    wait();

    // ...

}

或者,您可以通过在方法头中包含synchronized关键字(例如

)将整个方法声明为synchronized
public synchronized void foo () {

    // ...

    wait();

    // ...

}

只是一小段建议:通过创建多个线程并执行它们来实现多线程程序相当容易,但处理所创建内容的并发性是一项非常重要且具有挑战性的任务。 / p>

答案 2 :(得分:-2)

这类问题称为“Producer-Consumer problem”,根据您是否要在Java中使用信号量,监视器或现有的有界缓冲区,有几种方法可以解决它。 This tends to be a homework question,所以在我们为您提供更好的答案之前,我们可能需要了解您正在尝试做的事情。