为了提供上下文,我正在使用一个相当长的CSV文件,其中包含一列值,提供1960 - 2016年的平均日常温度,并使用BufferedReader
读取它们,如下所示:
BufferedReader br = new BufferedReader(new FileReader(new File("src/dailyTemp.csv")));
我还有一个Swing应用程序,它提供Boolean
值slowSpeed
,用于声明是否应该运行ScheduledExecutorService
。即它是否应该缓慢/快速。
此应用程序的当前用途是简单地调整是否立即返回下一个读取值或是否安排了它。
public static void main(String[] args) throws IOException
{
startGraph(); //This is the GUI that provides the state of the slowSpeed variable
final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
executorService.scheduleAtFixedRate(Main::readFileSlow, 0, 500, TimeUnit.MILLISECONDS);
BufferedReader br = new BufferedReader(new FileReader(new File("src/dailyTemp.csv")));
String newValue = "";
while (newValue != null)
{
if (slowSpeed)
{
newValue = readFileSlow(newValue, br);
} else
{
newValue = readFileFast(newValue, br);
}
totalCount++;
}
br.close();
System.out.println("FIN");
}
public static String readFileSlow(String newValue, BufferedReader br) throws IOException
{
while ((newValue = br.readLine()) != null)
{
System.out.println(newValue);
return newValue;
}
return null;
}
public static String readFileFast(String newValue, BufferedReader br) throws IOException
{
while ((newValue = br.readLine()) != null)
{
System.out.println(newValue);
return newValue;
}
return null;
}
必要的考虑是Reader
无法重新启动,因此存在while
循环来检查。
我遇到的主要问题是,readFileSlow()
函数无法使用变量,因此它不是Runnable
且无法由ScheduledExecutorService
控制。
编辑1
这是我的原始版本,合理地展示了它如何切换:
public class Main
{
static Boolean slowSpeed = true;
public static void main(String[] args) throws IOException, InterruptedException
{
startGraph();
BufferedReader br = new BufferedReader(new FileReader(new File("src/dailyTemp.csv")));
String newValue;
while ((newValue = br.readLine()) != null)
{
if (slowSpeed)
{
System.out.println(newValue);
doSomething(newValue);
TimeUnit.MILLISECONDS.sleep(500);
} else
{
System.out.println(newValue);
doSomething(newValue);
}
totalCount++;
}
br.close();
System.out.println("FIN");
}
public static void toggleSpeed(Boolean newSpeed)
{
slowSpeed = newSpeed;
System.out.println(slowSpeed);
}
}
答案 0 :(得分:2)
据我所知,readFileSlow
和readFileFast
是完全相同的。让我们假装它不是。关键是要有两种方法可以做不同的事情。
然后,让我们稍微修复readFileSlow
和readFileFast
。我只显示readFileSlow
,另一个看起来相同:
public static void readFileSlow(BufferedReader br) throws IOException
{
String newValue = null;
while ((newValue = br.readLine()) != null)
{
System.out.println(newValue);
return;
}
}
发生了什么事?
ScheduledExecutorService
调用它,那么返回的值无论如何都会丢弃。 schedule*
方法不会返回Future
-s来检索结果。如果是计划外阅读,即executorService.submit()
,我们可以使用返回值执行某些操作。但不是现在。String newValue
变量。由于该变量是在函数调用(按值传递)中复制的,因此我们可以定义一个具有相同名称的局部变量。结果将是相同的,但意图将更容易理解。忍受我,我们几乎就在那里。
你可以将这些函数调用包装成lambdas,如下所示:
final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
final BufferedReader br = new BufferedReader(new FileReader(new File("src/dailyTemp.csv")));
executorService.scheduleAtFixedRate(() -> {
try {
readFileSlow(br);
} catch (IOException e) {
throw new RuntimeException(e);
}
}, 0, 500, TimeUnit.MILLISECONDS);
我们需要try-catch
,因为Runnable
不应该抛出已检查Exception
- s。 RuntimeException
- s和Error
- s没关系。
您可以对实现Runnable
的自定义类执行相同的操作:
private static abstract class FileReaderTask implements Runnable {
protected BufferedReader br;
public FileReaderTask(BufferedReader br) {
this.br = br;
}
protected void doSomethingWithActualLine(String line) {
System.out.println(line);
}
}
private static class SlowFileReaderTask extends FileReaderTask {
public SlowFileReaderTask(BufferedReader br) {
super(br);
}
@Override
public void run() {
try {
String newValue = null;
while ((newValue = br.readLine()) != null)
{
doSomethingWithActualLine(newValue);
return;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
然后你可以像这样安排他们:
final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
final BufferedReader br = new BufferedReader(new FileReader(new File("src/dailyTemp.csv")));
executorService.scheduleAtFixedRate(new SlowFileReaderTask(br), 0, 500, TimeUnit.MILLISECONDS);
还有其他几个选项,例如将doSomethingWithActualLine()
中的FileReaderTask
方法替换为您为构造函数提供的lambda。你可以选择任何东西 - 取决于你想要做什么。