Java多线程 - 2个线程之间的通信

时间:2014-04-25 18:16:50

标签: java multithreading synchronization locking

我试图在java中学习多线程但我似乎无法在互联网上找到一些简单的例子来说明两个线程如何通信并在它们之间传递控制。例如;我想创建一个打印txt文件的简单程序,由2个线程组成:

  1. 线程(具有更高优先级)会询问每5行,如果我想继续下5行或终止程序

  2. 线程将控制打印以前1.线程允许的5行

  3. 我的主要问题是,如何让这些线程进入循环,因为我只能启动一次线程,我必须用1. thread启动程序。如果有人可以放一些简单的示例代码,其中2个线程与此程序通信或示例。

    感谢任何帮助,对不起,如果我忘记了一些关键信息。提前谢谢!

3 个答案:

答案 0 :(得分:1)

你在这里:

package test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Multithreader {

    /**
     * Needs to be volatile because the two thread communicate through it.
     * It is also very important that boolean updates and lookups are atomic,
     * we cannot do the same with for example a long!
     */
    volatile static boolean shouldFilePrinterPrint = false;

    public static void main(String[] args) throws IOException {

        // needs to be final so that the filePrinter can see it
        final BufferedReader br = new BufferedReader(new FileReader(new File("file.txt")));

        // this is the task of printing 5 lines from a file whenever shouldFilePrinterPrint is true
        Runnable filePrinter = new Runnable() {
            @Override
            public void run() {
                while(true){
                    if(shouldFilePrinterPrint){
                        shouldFilePrinterPrint=false;
                        String line;
                        int counter = 0;
                        try {
                            while (counter<5 && (line = br.readLine()) != null) {
                                counter++;
                                System.out.println(line);
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        };

        // this is the task that will set shouldFilePrinterPrint to true every time we push enter
        Runnable inputAwaiter = new Runnable(){
            @Override
            public void run() {
                while(true){
                    try {
                        System.in.read();
                        shouldFilePrinterPrint=true;
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }


            }
        };

        // we use the executor service to launch the two tasks in two threads
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        executorService.execute(filePrinter);
        executorService.execute(inputAwaiter);

        // I am omitting cleanup such as closing the reader, shutting down the executor service, etc.
        // and am just leaving the program to never terminate until manually stopped,
        // but such cleanup is very important in a real program!
    }
}

我认为这会实现您描述的行为。我跑了,它有效。

请注意,此处未提及“Thread”或“synchronized”。而是“executorService”和“Runnable”。这是有原因的,Joshua Bloch的Effective Java 2nd edition中详细介绍了这一点,我非常强烈推荐这本书。

答案 1 :(得分:0)

您对Java中的线程如何工作有一种固有的误解,根据您的陈述来判断&#34;显示2个线程如何进行通信并在它们之间传递控制权#34;。线程不会通过控制&#34;。你可以使用Thread 2 wait(),但即使Thread 1调用notify(),也无法保证哪个线程会被唤醒。实际上,线程1可能会持续执行一段时间。我建议您创建一个准备在线程1中打印的行队列,而不是尝试预测哪个线程将在正确的线程1中运行。当线程2唤醒时,检查线路是否准备就绪,如果没有,请返回睡眠。

如果使用wait和notify是您的作业的参数之一,那么此页面可以很好地解释如何正确使用它们:http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html。请注意,调用notify()并不能保证您想要的线程会被唤醒。总是使用警卫。

答案 2 :(得分:0)

我认为你对线程的作用有一个根本的误解。通过它的声音,你想要两个线程之间的顺序处理,实际上线程是并发的,即它们同时运行。

您可以使用Observer模式,其中打印线程观察输入线程。一旦输入线程有5行,它就会将它传递给观察者进行打印。结果是在输入线程接收更多数据时可以打印打印线程。