在新线程中打印时出现Java问题

时间:2018-08-10 09:42:27

标签: java multithreading

我已设置好代码,以便在Java程序的主线程上进行很长的处理时,将打开另一个线程以在控制台上显示加载动画,但这不起作用,并且仅显示加载动画线程关闭后立即执行所有操作。但是,如果我使用println()而不是print(),它将起作用,然后在线程按预期运行的同时每200毫秒打印一次点,但是我需要将它们打印在同一行上。请参见下面的代码。

主线程:

Thread animate = new Thread(new ConsoleAnimator(".",200));
animate.start();
//do stuff for a few seconds
animate.interrupt();

辅助线程:

public class ConsoleAnimator extends Thread{
    public int animateInterval;
    public String animateString;
    public ConsoleAnimator(String toAnimate, int interval){
        this.animateInterval = interval;
        this.animateString = toAnimate;
        this.setPriority(Thread.MAX_PRIORITY);
    }
    public void run(){
        try{
            while(true){
                Thread.sleep(animateInterval);
                refresh();
            }
        } catch(InterruptedException e){
            Thread.currentThread().interrupt();
        }
    }
    void refresh(){
        System.out.print(animateString);
        System.out.flush();
    }
    public void interrupt(){
        System.out.println();
        super.interrupt();
    }
}

非常感谢您的帮助

2 个答案:

答案 0 :(得分:2)

System.out被行缓冲。在输出到控制台之前,需要有一个换行符。

如果需要将其保留在同一行上,则可以选择使用“ Use System.err”(适合您的目的)。

如果将stderr重新连接到另一个输出(例如文件),则可以编写自己的console output

查看实际情况:https://ideone.com/mlyPdx

BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new
  FileOutputStream(FileDescriptor.out), "ASCII"), 512);
out.write("test");
out.flush();
out.write(" > ");
out.flush();
out.write("string");
out.flush();

这是在我的系统,Windows 7和cmd上运行的代码

import java.util.*;
import java.lang.*;
import java.io.*;

/* Name of the class has to be "Main" only if the class is public. */
public class Test
{
    public static void main (String[] args) throws java.lang.Exception
    {

     Thread animate = new Thread(new ConsoleAnimator(".",200));
     animate.start();
     for(int c =0; c < 20; c++) {
         Thread.sleep(1000);
     }
     animate.interrupt();

    }
}
class ConsoleAnimator extends Thread{
    public int animateInterval;
    public String animateString;
    protected BufferedWriter out;

    public ConsoleAnimator(String toAnimate, int interval) throws IOException {
        this.animateInterval = interval;
        this.animateString = toAnimate;
        this.setPriority(Thread.MAX_PRIORITY);

            this.out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(FileDescriptor.out), "ASCII"), 512);

    }

    public void run(){
        try{
            while(true){
                Thread.sleep(animateInterval);
                refresh();
            }
        } catch(InterruptedException e){
            Thread.currentThread().interrupt();
        }
        catch( Exception e) {
            Thread.currentThread().interrupt();
        }
    }
    void refresh() {
        try {
            this.out.write(animateString);
            this.out.flush();
        }
        catch(IOException ex) {

        }
    }
    public void interrupt() {
        try {
            this.out.write(System.lineSeparator());
            this.out.flush();
        }
        catch(IOException ex) {

        }
        super.interrupt();
    }
}

enter image description here

答案 1 :(得分:1)

为什么不使用诸如progressbarjava-progressbar之类的某些库? 如果您想知道为什么代码不起作用,则可以查找这些库的代码。