Java 终端中的数据循环打印可由用户输入终止
我的任务是在终端中打印货币汇率表,并每分钟延迟打印一次。在用户输入时,我将结束循环并返回海关终端菜单。如何做到这一点 总的来说,我有一个问题需要弄清楚如何拥有无缝的用户体验。我需要在终端中有用户输入,如果没有用户操作,仍然每分钟打印数据。最后,如果用户决定终止打印,那么如何终止整个数据打印循环?->runFlag= 这真的是正确的方法吗 我尝试过几种方法,但不幸的是,这些方法一直在起作用 有人能帮我吗 到目前为止,我只有以下代码。在循环中打印汇率的自定义方法:Java 终端中的数据循环打印可由用户输入终止,java,concurrency,terminal,Java,Concurrency,Terminal,我的任务是在终端中打印货币汇率表,并每分钟延迟打印一次。在用户输入时,我将结束循环并返回海关终端菜单。如何做到这一点 总的来说,我有一个问题需要弄清楚如何拥有无缝的用户体验。我需要在终端中有用户输入,如果没有用户操作,仍然每分钟打印数据。最后,如果用户决定终止打印,那么如何终止整个数据打印循环?->runFlag= 这真的是正确的方法吗 我尝试过几种方法,但不幸的是,这些方法一直在起作用 有人能帮我吗 到目前为止,我只有以下代码。在循环中打印汇率的自定义方法: private void prin
private void printExchangeRateTable(最终地图存储dexChangeRates){
布尔runFlag=true;
做{
打印汇率(存储汇率);
println(“按任意键停止循环”);
线程延迟器=新线程(新延迟器());
Thread threadListeningUserInput=新线程(新的UserInputListener());
threadDelayer.start();
threadListeningUserInput.start();
runFlag=????;
}while(runFlag);
}
延迟对象
final class Delayer implements Runnable {
public static final long MILISECONDS = 1000L;
@Override
public void run(){
try {
Thread.sleep(60 * MILISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
用户输入侦听器
class UserInputListener implements Runnable {
@Override
public void run() {
Scanner scanner = new Scanner(System.in);
val userInput = scanner.nextLine();
if(userInput != null) {
Thread.currentThread().interrupt();
}
}
}
你可以试试这个。我使用与您相同的逻辑读取用户输入,但对于打印,我将使用计时器(此处计划每1秒运行一次,但您可以更改)。管理计时器更容易,可以从另一个线程取消
public class Main {
public static void main(String[] args) {
Thread inputListener = new Thread(new UserInputListener());
inputListener.start();
}
static class MyTimerTask extends TimerTask
{
public void run()
{
System.out.println("some output");
}
}
static class UserInputListener implements Runnable {
@Override
public void run() {
Timer timer = new Timer();
TimerTask task = new MyTimerTask();
timer.schedule(task, 0, 1000);
Scanner scanner = new Scanner(System.in);
scanner.nextLine();
timer.cancel();
}
}
}
首先,您需要两个线程,但不必创建两个线程-您可以使用主线程进行用户输入,并在程序开始时启动另一个线程,该线程将每分钟打印货币汇率 每个线程内部都有一个无限(或标记控制)循环。但是,与其自己管理,我建议您使用
ScheduledExecutorService
,否则您将很难中断线程
以下是一个例子:
import java.util.Scanner;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Example {
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleWithFixedDelay(Example::printData, 1, 1, TimeUnit.MINUTES);
Scanner scanner = new Scanner(System.in);
while (true) {
String userInput = scanner.nextLine();
if (userInput.equals("exit")) {
break;
}
}
executor.shutdown();
}
private static void printData() {
System.out.println("data");
}
}
如果没有其他用户输入要处理,并且它仅用于停止后台线程,则此线程中根本不需要循环,您可以将其简化为:
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleWithFixedDelay(Example::printData, 1, 1, TimeUnit.MINUTES);
Scanner scanner = new Scanner(System.in);
scanner.nextLine();
executor.shutdown();
}
您可以使用设置一个重复任务,但是在这里,将用户输入的读数发送到后台任务要容易得多
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
CompletableFuture<String> userInput = CompletableFuture.supplyAsync(s::nextLine);
while(!userInput.isDone()) {
printData();
try {
userInput.get(1, TimeUnit.MINUTES);
}
catch(ExecutionException|InterruptedException ex) {} // handled after the loop
catch(TimeoutException ex) {
continue;
}
}
String input = userInput.join();
// handle input
}
private static void printData() {
System.out.println("data");
}
不要使用
java.util.Timer
。遗憾的是,这个东西还没有标记为不推荐。改用a,例如。
Scanner s = new Scanner(System.in);
for(boolean quit = false; !quit; ) {
CompletableFuture<String> userInput = CompletableFuture.supplyAsync(s::nextLine);
while(!userInput.isDone()) {
printData();
try {
userInput.get(1, TimeUnit.MINUTES);
}
catch(ExecutionException|InterruptedException ex) {} // handled implicitly
catch(TimeoutException ex) {
continue;
}
}
String input = userInput.join();
// handle input
if(input.equals("exit")) quit = true;
}