使用线程会扰乱我的暂停系统
Use of a thread messes up my pausing system
我的代码有问题。计时器总体上似乎工作正常,暂停按钮也能正常工作。
问题是当您在特定时间暂停时钟然后取消暂停时。
如果我们(比方说)在 8 秒暂停并在一分钟后取消暂停,它不会像 9-10-11 那样继续运行,等等。它会运行 74-75-76...(我把它分成分钟和秒)。
是线程导致的问题吗? (此外,我过度使用了 freeze_sec 和 freeze_min 时间代码片段,只是为了看看它是否会被修复,但事实并非如此。)
代码如下:
Thread t1 = null;
ss = new ServerSocket(6800);
while(true) {
s = ss.accept();
isr = new InputStreamReader(s.getInputStream());
br = new BufferedReader(isr);
message = br.readLine();
if (message.equals("START")) {
t1 = new Thread(new Thread1());
t1.start();
...
} else if (message.equals("PAUSE")) {
if(check) {
try {
check = false;
Thread1.PAUSE(true);
} catch (Exception e) {
System.out.println("Exception e");
}
} else {
check = true;
Thread1.PAUSE(false);
}
}
Thread1 class 看起来像:
import java.io.*;
import java.util.Date;
import java.util.Scanner;
public class Thread1 extends MyServerFrame implements Runnable{
private static int current_min_time = 0;
private static int current_sec_time = 0;
private static int freeze_min_time = 0;
private static int freeze_sec_time = 0;
private static boolean pause = false;
private static int minutes = 0;
private int total_time_sec = 0;
private static boolean freeze_signal = false;
private static int k = 0;
@Override
public void run() {
long elapsedTime = 0L;
boolean bool = true;
int num = 0;
while (bool) {
Scanner scan = new Scanner(System.in);
if (minutes == 0) {
System.out.println("How many minutes for this half-time?");
Scanner in = new Scanner(System.in);
num = in.nextInt();
minutes = num;
}
long startTime = System.currentTimeMillis();
while (total_time_sec < minutes * 60 || freeze_signal == false) {
if (freeze_signal && k == 0) {
freeze_sec_time = current_sec_time;
freeze_min_time = current_min_time;
k++;
}
if (!pause) {
//perform db poll/check
if (elapsedTime / 1000 != current_sec_time) {
try {
clearTheFile("Half_Time.txt");
} catch (IOException e) {
System.out.println("Exception");
}
if (!freeze_signal && k > 0) {
current_sec_time = freeze_sec_time;
current_min_time = freeze_min_time;
k = 0;
}
current_sec_time++;
total_time_sec = current_sec_time + current_min_time / 60;
print_in_txt();
}
elapsedTime = (new Date()).getTime() - startTime;
if (current_sec_time == 60) {
if (!freeze_signal && k > 0) {
current_sec_time = freeze_sec_time;
current_min_time = freeze_min_time;
try {
clearTheFile("Half_Time.txt");
} catch (IOException e) {
System.out.println("Exception");
}
print_in_txt();
k = 0;
}
current_sec_time = 0;
current_min_time++;
total_time_sec = current_sec_time + current_min_time / 60;
startTime = System.currentTimeMillis();
elapsedTime = (new Date()).getTime() - startTime;
try {
clearTheFile("Half_Time.txt");
} catch (IOException e) {
System.out.println("Exception");
}
print_in_txt();
}
}
}
}
}
public static void clearTheFile(String txt_name) throws IOException {
try {
FileWriter fwOb = new FileWriter(txt_name, false);
PrintWriter pwOb = new PrintWriter(fwOb, false);
pwOb.flush();
pwOb.close();
fwOb.close();
} catch (IOException e) {}
}
public static void print_in_txt() {
PrintWriter out;
try {
out = new PrintWriter("Half_Time.txt");
out.println(String.format("%02d", current_min_time) + ":" + String.format("%02d", current_sec_time));
out.print("");
out.close();
} catch (FileNotFoundException e) {
System.err.println("File doesn't exist");
e.printStackTrace();
}
}
public static void PAUSE(boolean p) {
if (p) {
pause = true;
freeze_signal = true;
} else {
current_sec_time = freeze_sec_time;
current_min_time = freeze_min_time;
try {
clearTheFile("Half_Time.txt");
} catch (IOException e) {
System.out.println("Exception");
}
print_in_txt();
pause = false;
freeze_signal = false;
}
}
}
所以,在花了一些时间思考这个想法之后,我突然意识到你实际上根本不需要线程。
您需要的是一种计算时间点之间持续时间的方法,它不需要线程来更新状态,它是自动完成的。
线程正在做"other stuff"
所以,基于此,我从我的 ...
中拿了一个 StopWatch
class
public class StopWatch {
private Instant startTime;
private Duration totalRunTime = Duration.ZERO;
public StopWatch start() {
startTime = Instant.now();
return this;
}
public StopWatch stop() {
Duration runTime = Duration.between(startTime, Instant.now());
totalRunTime = totalRunTime.plus(runTime);
startTime = null;
return this;
}
public StopWatch pause() {
return stop();
}
public StopWatch resume() {
return start();
}
public StopWatch reset() {
stop();
totalRunTime = Duration.ZERO;
return this;
}
public boolean isRunning() {
return startTime != null;
}
public Duration getDuration() {
Duration currentDuration = Duration.ZERO;
currentDuration = currentDuration.plus(totalRunTime);
if (isRunning()) {
Duration runTime = Duration.between(startTime, Instant.now());
currentDuration = currentDuration.plus(runTime);
}
return currentDuration;
}
}
并应用它可以在 Thread
内使用,这将简单地打印 运行 时间。
围绕这一点,我添加了暂停、恢复和停止线程的功能,以演示基本思想...
public class StopWatchRunnable implements Runnable {
private final Lock pauseLock = new ReentrantLock();
private final Condition pauseCondtion = pauseLock.newCondition();
private final AtomicBoolean isPaused = new AtomicBoolean(false);
private final AtomicBoolean isRunning = new AtomicBoolean(true);
private final StopWatch stopWatch = new StopWatch();
@Override
public void run() {
stopWatch.start();
while (isRunning.get()) {
while (isPaused.get()) {
pauseLock.lock();
stopWatch.pause();
try {
pauseCondtion.await();
} catch (InterruptedException ex) {
} finally {
pauseLock.unlock();
stopWatch.resume();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
Duration duration = stopWatch.getDuration();
String formatted = String.format("%dhrs %02dmins, %02dseconds", duration.toHours(), duration.toMinutesPart(), duration.toSecondsPart());
System.out.println(formatted);
}
}
public void stop() {
pauseLock.lock();
try {
isPaused.set(false);
isRunning.set(false);
} finally {
pauseCondtion.signalAll();
pauseLock.unlock();
}
}
public void pause() {
pauseLock.lock();
try {
isPaused.set(true);
} finally {
pauseLock.unlock();
}
}
public void resume() {
pauseLock.lock();
try {
isPaused.set(false);
} finally {
pauseCondtion.signalAll();
pauseLock.unlock();
}
}
}
可运行示例...
这基本上是从上面获取代码并将其转储到一个简单的可运行示例中,该示例演示了 pause/resume 功能
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class StopWatchExample {
public static void main(String[] args) throws InterruptedException {
new StopWatchExample();
}
public StopWatchExample() throws InterruptedException {
StopWatchRunnable stopWatch = new StopWatchRunnable();
Thread thread = new Thread(stopWatch);
thread.start();
Thread.sleep(5000);
System.out.println("Pause...");
stopWatch.pause();
Thread.sleep(5000);
System.out.println("Resume...");
stopWatch.resume();
Thread.sleep(5000);
System.out.println("Stop...");
stopWatch.stop();
thread.join();
System.out.println("All done...");
}
public class StopWatch {
private Instant startTime;
private Duration totalRunTime = Duration.ZERO;
public StopWatch start() {
startTime = Instant.now();
return this;
}
public StopWatch stop() {
Duration runTime = Duration.between(startTime, Instant.now());
totalRunTime = totalRunTime.plus(runTime);
startTime = null;
return this;
}
public StopWatch pause() {
return stop();
}
public StopWatch resume() {
return start();
}
public StopWatch reset() {
stop();
totalRunTime = Duration.ZERO;
return this;
}
public boolean isRunning() {
return startTime != null;
}
public Duration getDuration() {
Duration currentDuration = Duration.ZERO;
currentDuration = currentDuration.plus(totalRunTime);
if (isRunning()) {
Duration runTime = Duration.between(startTime, Instant.now());
currentDuration = currentDuration.plus(runTime);
}
return currentDuration;
}
}
public class StopWatchRunnable implements Runnable {
private final Lock pauseLock = new ReentrantLock();
private final Condition pauseCondtion = pauseLock.newCondition();
private final AtomicBoolean isPaused = new AtomicBoolean(false);
private final AtomicBoolean isRunning = new AtomicBoolean(true);
private final StopWatch stopWatch = new StopWatch();
@Override
public void run() {
stopWatch.start();
while (isRunning.get()) {
while (isPaused.get()) {
pauseLock.lock();
stopWatch.pause();
try {
pauseCondtion.await();
} catch (InterruptedException ex) {
} finally {
pauseLock.unlock();
stopWatch.resume();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
Duration duration = stopWatch.getDuration();
String formatted = String.format("%dhrs %02dmins, %02dseconds", duration.toHours(), duration.toMinutesPart(), duration.toSecondsPart());
System.out.println(formatted);
}
}
public void stop() {
pauseLock.lock();
try {
isPaused.set(false);
isRunning.set(false);
} finally {
pauseCondtion.signalAll();
pauseLock.unlock();
}
}
public void pause() {
pauseLock.lock();
try {
isPaused.set(true);
} finally {
pauseLock.unlock();
}
}
public void resume() {
pauseLock.lock();
try {
isPaused.set(false);
} finally {
pauseCondtion.signalAll();
pauseLock.unlock();
}
}
}
}
我的代码有问题。计时器总体上似乎工作正常,暂停按钮也能正常工作。
问题是当您在特定时间暂停时钟然后取消暂停时。
如果我们(比方说)在 8 秒暂停并在一分钟后取消暂停,它不会像 9-10-11 那样继续运行,等等。它会运行 74-75-76...(我把它分成分钟和秒)。
是线程导致的问题吗? (此外,我过度使用了 freeze_sec 和 freeze_min 时间代码片段,只是为了看看它是否会被修复,但事实并非如此。)
代码如下:
Thread t1 = null;
ss = new ServerSocket(6800);
while(true) {
s = ss.accept();
isr = new InputStreamReader(s.getInputStream());
br = new BufferedReader(isr);
message = br.readLine();
if (message.equals("START")) {
t1 = new Thread(new Thread1());
t1.start();
...
} else if (message.equals("PAUSE")) {
if(check) {
try {
check = false;
Thread1.PAUSE(true);
} catch (Exception e) {
System.out.println("Exception e");
}
} else {
check = true;
Thread1.PAUSE(false);
}
}
Thread1 class 看起来像:
import java.io.*;
import java.util.Date;
import java.util.Scanner;
public class Thread1 extends MyServerFrame implements Runnable{
private static int current_min_time = 0;
private static int current_sec_time = 0;
private static int freeze_min_time = 0;
private static int freeze_sec_time = 0;
private static boolean pause = false;
private static int minutes = 0;
private int total_time_sec = 0;
private static boolean freeze_signal = false;
private static int k = 0;
@Override
public void run() {
long elapsedTime = 0L;
boolean bool = true;
int num = 0;
while (bool) {
Scanner scan = new Scanner(System.in);
if (minutes == 0) {
System.out.println("How many minutes for this half-time?");
Scanner in = new Scanner(System.in);
num = in.nextInt();
minutes = num;
}
long startTime = System.currentTimeMillis();
while (total_time_sec < minutes * 60 || freeze_signal == false) {
if (freeze_signal && k == 0) {
freeze_sec_time = current_sec_time;
freeze_min_time = current_min_time;
k++;
}
if (!pause) {
//perform db poll/check
if (elapsedTime / 1000 != current_sec_time) {
try {
clearTheFile("Half_Time.txt");
} catch (IOException e) {
System.out.println("Exception");
}
if (!freeze_signal && k > 0) {
current_sec_time = freeze_sec_time;
current_min_time = freeze_min_time;
k = 0;
}
current_sec_time++;
total_time_sec = current_sec_time + current_min_time / 60;
print_in_txt();
}
elapsedTime = (new Date()).getTime() - startTime;
if (current_sec_time == 60) {
if (!freeze_signal && k > 0) {
current_sec_time = freeze_sec_time;
current_min_time = freeze_min_time;
try {
clearTheFile("Half_Time.txt");
} catch (IOException e) {
System.out.println("Exception");
}
print_in_txt();
k = 0;
}
current_sec_time = 0;
current_min_time++;
total_time_sec = current_sec_time + current_min_time / 60;
startTime = System.currentTimeMillis();
elapsedTime = (new Date()).getTime() - startTime;
try {
clearTheFile("Half_Time.txt");
} catch (IOException e) {
System.out.println("Exception");
}
print_in_txt();
}
}
}
}
}
public static void clearTheFile(String txt_name) throws IOException {
try {
FileWriter fwOb = new FileWriter(txt_name, false);
PrintWriter pwOb = new PrintWriter(fwOb, false);
pwOb.flush();
pwOb.close();
fwOb.close();
} catch (IOException e) {}
}
public static void print_in_txt() {
PrintWriter out;
try {
out = new PrintWriter("Half_Time.txt");
out.println(String.format("%02d", current_min_time) + ":" + String.format("%02d", current_sec_time));
out.print("");
out.close();
} catch (FileNotFoundException e) {
System.err.println("File doesn't exist");
e.printStackTrace();
}
}
public static void PAUSE(boolean p) {
if (p) {
pause = true;
freeze_signal = true;
} else {
current_sec_time = freeze_sec_time;
current_min_time = freeze_min_time;
try {
clearTheFile("Half_Time.txt");
} catch (IOException e) {
System.out.println("Exception");
}
print_in_txt();
pause = false;
freeze_signal = false;
}
}
}
所以,在花了一些时间思考这个想法之后,我突然意识到你实际上根本不需要线程。
您需要的是一种计算时间点之间持续时间的方法,它不需要线程来更新状态,它是自动完成的。
线程正在做"other stuff"
所以,基于此,我从我的
StopWatch
class
public class StopWatch {
private Instant startTime;
private Duration totalRunTime = Duration.ZERO;
public StopWatch start() {
startTime = Instant.now();
return this;
}
public StopWatch stop() {
Duration runTime = Duration.between(startTime, Instant.now());
totalRunTime = totalRunTime.plus(runTime);
startTime = null;
return this;
}
public StopWatch pause() {
return stop();
}
public StopWatch resume() {
return start();
}
public StopWatch reset() {
stop();
totalRunTime = Duration.ZERO;
return this;
}
public boolean isRunning() {
return startTime != null;
}
public Duration getDuration() {
Duration currentDuration = Duration.ZERO;
currentDuration = currentDuration.plus(totalRunTime);
if (isRunning()) {
Duration runTime = Duration.between(startTime, Instant.now());
currentDuration = currentDuration.plus(runTime);
}
return currentDuration;
}
}
并应用它可以在 Thread
内使用,这将简单地打印 运行 时间。
围绕这一点,我添加了暂停、恢复和停止线程的功能,以演示基本思想...
public class StopWatchRunnable implements Runnable {
private final Lock pauseLock = new ReentrantLock();
private final Condition pauseCondtion = pauseLock.newCondition();
private final AtomicBoolean isPaused = new AtomicBoolean(false);
private final AtomicBoolean isRunning = new AtomicBoolean(true);
private final StopWatch stopWatch = new StopWatch();
@Override
public void run() {
stopWatch.start();
while (isRunning.get()) {
while (isPaused.get()) {
pauseLock.lock();
stopWatch.pause();
try {
pauseCondtion.await();
} catch (InterruptedException ex) {
} finally {
pauseLock.unlock();
stopWatch.resume();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
Duration duration = stopWatch.getDuration();
String formatted = String.format("%dhrs %02dmins, %02dseconds", duration.toHours(), duration.toMinutesPart(), duration.toSecondsPart());
System.out.println(formatted);
}
}
public void stop() {
pauseLock.lock();
try {
isPaused.set(false);
isRunning.set(false);
} finally {
pauseCondtion.signalAll();
pauseLock.unlock();
}
}
public void pause() {
pauseLock.lock();
try {
isPaused.set(true);
} finally {
pauseLock.unlock();
}
}
public void resume() {
pauseLock.lock();
try {
isPaused.set(false);
} finally {
pauseCondtion.signalAll();
pauseLock.unlock();
}
}
}
可运行示例...
这基本上是从上面获取代码并将其转储到一个简单的可运行示例中,该示例演示了 pause/resume 功能
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class StopWatchExample {
public static void main(String[] args) throws InterruptedException {
new StopWatchExample();
}
public StopWatchExample() throws InterruptedException {
StopWatchRunnable stopWatch = new StopWatchRunnable();
Thread thread = new Thread(stopWatch);
thread.start();
Thread.sleep(5000);
System.out.println("Pause...");
stopWatch.pause();
Thread.sleep(5000);
System.out.println("Resume...");
stopWatch.resume();
Thread.sleep(5000);
System.out.println("Stop...");
stopWatch.stop();
thread.join();
System.out.println("All done...");
}
public class StopWatch {
private Instant startTime;
private Duration totalRunTime = Duration.ZERO;
public StopWatch start() {
startTime = Instant.now();
return this;
}
public StopWatch stop() {
Duration runTime = Duration.between(startTime, Instant.now());
totalRunTime = totalRunTime.plus(runTime);
startTime = null;
return this;
}
public StopWatch pause() {
return stop();
}
public StopWatch resume() {
return start();
}
public StopWatch reset() {
stop();
totalRunTime = Duration.ZERO;
return this;
}
public boolean isRunning() {
return startTime != null;
}
public Duration getDuration() {
Duration currentDuration = Duration.ZERO;
currentDuration = currentDuration.plus(totalRunTime);
if (isRunning()) {
Duration runTime = Duration.between(startTime, Instant.now());
currentDuration = currentDuration.plus(runTime);
}
return currentDuration;
}
}
public class StopWatchRunnable implements Runnable {
private final Lock pauseLock = new ReentrantLock();
private final Condition pauseCondtion = pauseLock.newCondition();
private final AtomicBoolean isPaused = new AtomicBoolean(false);
private final AtomicBoolean isRunning = new AtomicBoolean(true);
private final StopWatch stopWatch = new StopWatch();
@Override
public void run() {
stopWatch.start();
while (isRunning.get()) {
while (isPaused.get()) {
pauseLock.lock();
stopWatch.pause();
try {
pauseCondtion.await();
} catch (InterruptedException ex) {
} finally {
pauseLock.unlock();
stopWatch.resume();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
Duration duration = stopWatch.getDuration();
String formatted = String.format("%dhrs %02dmins, %02dseconds", duration.toHours(), duration.toMinutesPart(), duration.toSecondsPart());
System.out.println(formatted);
}
}
public void stop() {
pauseLock.lock();
try {
isPaused.set(false);
isRunning.set(false);
} finally {
pauseCondtion.signalAll();
pauseLock.unlock();
}
}
public void pause() {
pauseLock.lock();
try {
isPaused.set(true);
} finally {
pauseLock.unlock();
}
}
public void resume() {
pauseLock.lock();
try {
isPaused.set(false);
} finally {
pauseCondtion.signalAll();
pauseLock.unlock();
}
}
}
}