我知道这是一个可能重复的常见问题,但是我读过的许多方法都不适用于我。
我有一个简单的程序,可以使用线程重新创建经典的生产者-消费者同步问题。
练习的一部分是将输出到控制台以及文本文件。
我的代码如下:
class ProcessDemo
{
static int done = 0;
//main method to instantiate both thread processes
public static void main(String[]args) throws InterruptedException
{
final ProducerConsumer PC = new ProducerConsumer();
//instantiation of a new thread object, inside of which the run method is overridden
Thread producer = new Thread(new Runnable()
{
@Override
public void run()
{
try {
PC.produce();
}
catch(InterruptedException e){
e.printStackTrace();
}
}
});
//instantiate second thread object, inside of which the run method is overridden
Thread consumer = new Thread(new Runnable()
{
@Override
public void run()
{
try {
PC.consume();
}
catch(InterruptedException e){
e.printStackTrace();
}
}
});
//calling the start method to initiate both the producer and consumer threads
producer.start();
consumer.start();
}
public static class ProducerConsumer
{
int[] buffer = new int[5];
int capacity = 5;
int counter = 0;
int producerIndex = 0;
int consumerIndex = 0;
static int done = 0;
public void consume() throws InterruptedException
{
PrintWriter output = null;
try
{
//instantiating print writer object to output results to a designated file
output = new PrintWriter("results.txt");
}
catch (FileNotFoundException e1) {
e1.printStackTrace();
}
while (true)
{
long sleepTimeout = (long)(((Math.random()*2000.00)+2000.00));
Thread.sleep((long)(sleepTimeout));
System.out.println("consumer random sleep for " + sleepTimeout/1000.00 + " seconds");
output.println("consumer random sleep for " + sleepTimeout/1000.00 + " seconds");
while (producerIndex == consumerIndex && done != 1)
{
System.out.println("\n*****BUFFER EMPTY, consumer sleeping for 1 sec\n");
output.println("\n*****BUFFER EMPTY, consumer sleeping for 1 sec\n");
Thread.sleep(1000);
}
int valueRead = buffer[consumerIndex];
System.out.println("\nConsumer consumed item : " + valueRead + " from index: " + consumerIndex);
output.println("\nConsumer consumed item : " + valueRead + " from index: " + consumerIndex);
consumerIndex = (consumerIndex + 1)%capacity;
counter--;
System.out.println("counter is now: " + counter);
output.println("number of full slots in buffer: " + counter);
if (counter == 0 && done == 1)
{
System.out.println("-------------All Done---------------");
output.println("-------------All Done---------------");
break;
}
}
}
}
}
当我在创建的两个线程对象中覆盖run()方法,然后将print语句放置在run方法中时,我可以使用以下代码输出到控制台和指定文件:
PrintWriter output = null;
try
{
output = new PrintWriter("results.txt");
}
catch (FileNotFoundException e1) {
e1.printStackTrace();
}
System.out.println("print something to console");
output.println("print something to output file");
但是,当将打印语句和打印编写器对象移出线程对象并移至我在单独的类(公共静态类ProducerConsumer)中定义的“ produce”和“ consume”方法中时,尽管控制台输出很好,输出文件为空白。
在这种情况下,我不得不使用以下技术:
outputFile = new File(outputFileName);
output_obj = new PrintStream(outputFile);
console = System.out;
System.setOut(output_obj);
System.out.println("print something to output file");
System.setOut(console);
System.out.println("print something to console");
这是同时输出到控制台和文本文件的最佳方法吗?感觉这种方法可能不是最有效的。另一件事是,我必须复制打印语句,这会增加代码的大量内容,如果有更好的方法来实现此功能,我将非常有兴趣学习它。