[英]How to pause/resume all threads in an ExecutorService in Java?
[英]How to pause / resume Java Threads
我正在用Java制作井字游戲程序,因為我正在學習Java,並且我認為一個簡單的項目將是一個不錯的起點。 到目前為止,這是我的代碼:
public class Start {
public static void main(String[] args) {
GameTicTacToe gameTicTacToe = new GameTicTacToe();
gameTicTacToe.windowBirth();
}
}
和,
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GameTicTacToe implements ActionListener {
private int gridSize = 3;
private JButton[] gridButton = new JButton[(gridSize * gridSize)];
private JPanel grid = new JPanel(new GridLayout(gridSize, gridSize, 0, 0));
private JFrame windowTicTacToe = new JFrame("Tisk, Task, Toes");
private int[] gridButtonOwner = new int[(gridSize * gridSize)];
private int turn = 1;
private int HolerHor, HolerVer, HolerDia1, HolerDia2;
Thread winnerBlue = new Thread() {
public void run() {
for (int a = 0; a < 4; a++) {
for (int i = 0; i < gridButton.length; i++) {
gridButton[i].setBackground(Color.BLUE);
}
try {
Thread.sleep(300);
} catch (InterruptedException e) {
}
for (int i = 0; i < gridButton.length; i++) {
gridButton[i].setBackground(Color.WHITE);
}
try {
Thread.sleep(300);
} catch (InterruptedException e) {
}
}
for (int i = 0; i < gridButton.length; i++) {
gridButton[i].setEnabled(true);
gridButtonOwner[i] = 0;
}
}
};
Thread winnerRed = new Thread() {
public void run() {
for (int a = 0; a < 4; a++) {
for (int i = 0; i < gridButton.length; i++) {
gridButton[i].setBackground(Color.RED);
}
try {
Thread.sleep(300);
} catch (InterruptedException e) {
}
for (int i = 0; i < gridButton.length; i++) {
gridButton[i].setBackground(Color.WHITE);
}
try {
Thread.sleep(300);
} catch (InterruptedException e) {
}
}
for (int i = 0; i < gridButton.length; i++) {
gridButton[i].setEnabled(true);
gridButtonOwner[i] = 0;
}
}
};
public void windowBirth() {
for (int i = 0; i < gridButton.length; i++) {
gridButtonOwner[i] = 0;
gridButton[i] = new JButton("");
gridButton[i].addActionListener(this);
gridButton[i].setBackground(Color.WHITE);
grid.add(gridButton[i]);
}
windowTicTacToe.setDefaultCloseOperation(3);
windowTicTacToe.setLocation(400, 200);
windowTicTacToe.setPreferredSize(new Dimension(400, 400));
windowTicTacToe.add(grid);
windowTicTacToe.pack();
windowTicTacToe.setVisible(true);
}
public void actionPerformed(ActionEvent gridButtonClicked) {
for (int i = 0; i < gridButton.length; i++) {
if (gridButtonClicked.getSource() == gridButton[i]) {
if (turn == 1) {
turn = 2;
gridButtonOwner[i] = 1;
gridButton[i].setBackground(Color.blue);
gridButton[i].setEnabled(false);
} else {
turn = 1;
gridButtonOwner[i] = 2;
gridButton[i].setBackground(Color.red);
gridButton[i].setEnabled(false);
}
}
}
checkWinner();
}
public void checkWinner() {
for (int a = 1; a < 3; a++) {
HolerDia1 = a;
HolerDia2 = a;
for (int b = 0; b < gridSize; b++) {
HolerHor = a;
HolerVer = a;
for (int c2 = 0; c2 < gridSize; c2++) {
HolerHor = (HolerHor * gridButtonOwner[((b * gridSize) + c2)])/ a;
HolerVer = (HolerVer * gridButtonOwner[((c2 * gridSize) + b)])/ a;
}
if (HolerHor == a || HolerVer == a) {
winnerAnimation(a);
}
}
for(int h = 0;h < gridSize; h++){
HolerDia1 = (HolerDia1 * gridButtonOwner[h * (gridSize + 1)]) / a;
HolerDia2 = (HolerDia2 * gridButtonOwner[(h * (gridSize - 1)) + (gridSize - 1)]) / a;
}
if (HolerDia1 == a || HolerDia2 == a) {
winnerAnimation(a);
}
}
}
public void winnerAnimation(int b) {
for (int i = 0; i < gridButton.length; i++) {
gridButton[i].setEnabled(false);
}
if (b == 1){
winnerBlue.start();
}else{
winnerRed.start();
}
}
}
這是我的問題,當玩家獲勝時,例如玩家1(藍色),它將播放動畫(將棋盤閃爍藍色)。 但是當玩家1再次獲勝時,程序崩潰。
我仔細研究了一下,發現您無法啟動線程兩次,因為您無法啟動。
我該如何暫停線程,然后在需要時重新啟動它?
您可以簡單地創建一個新線程並在需要時運行它。 但是無論如何,我都會使用Swing計時器來制作動畫,因為它更簡單,更安全,因為您不必擔心由於意外踩到Swing線程EDT而造成的間歇性崩潰。
例如
public void myWinner(final Color flashColor) {
int timerDelay = 300;
new javax.swing.Timer(timerDelay , new ActionListener() {
private static final int COUNTER_MAX = 5;
int counter = 0;
public void actionPerformed(ActionEvent e) {
if (counter >= COUNTER_MAX) { // time to stop
((Timer)e.getSource()).stop();
for (int i = 0; i < gridButton.length; i++) {
gridButton[i].setBackground(Color.white); // just to be sure
gridButton[i].setEnabled(true);
gridButtonOwner[i] = 0;
}
}
Color bckgrndColor = (counter % 2 == 0) ? flashColor : Color.white;
for (JButton button : gridButton) {
button.setBackground(bckgrndColor);
}
counter++;
}
}).start();
}
在您的情況下,在重播動畫線程時,您可能需要:
Runnable
對象,例如,創建匿名匿名Runnable
而不是創建匿名Thread
對象。 然后只需重新創建線程並啟動它:
public void winnerAnimation(int b) { ... if (b == 1) { animationThread = new Thread(winnerBlue); animationThread.start(); } else { animationThread = new Thread(winnerRed); animationThread.start(); } }
順便說一句,您可能需要考慮以下事實:在編寫Thread
或Runnable
時,Swing不是線程安全的。
使用信號量 。
創建線程的另一個實例怎么了? 重用線程是令人討厭的,會導致真正奇怪的行為,通常不應該這樣做。
除了重復代碼(線程中只有1行不同,對嗎?),您可以簡單地將線程實現為內部類。 這樣,您不必使用匿名實例,並且可以重新創建和啟動任意多次。
您應該明確考慮將顏色添加為該線程的參數!
(我很確定這里有一個編譯器錯誤,但是您應該明白我的意思。)
// other stuff here...
public void winnerAnimation(int b) {
for (int i = 0; i < gridButton.length; i++) {
gridButton[i].setEnabled(false);
}
if (b == 1){
new WinnerThread(Color.BLUE).start();
}else{
new WinnerThread(Color.RED).start();
}
}
class WinnerThread extends Thread {
private Color color;
public WinnerThread(Color c)
{
color = c;
}
public void run() {
for (int a = 0; a < 4; a++) {
for (int i = 0; i < gridButton.length; i++) {
gridButton[i].setBackground(color);
}
try {
Thread.sleep(300);
} catch (InterruptedException e) {
}
for (int i = 0; i < gridButton.length; i++) {
gridButton[i].setBackground(Color.WHITE);
}
try {
Thread.sleep(300);
} catch (InterruptedException e) {
}
}
for (int i = 0; i < gridButton.length; i++) {
gridButton[i].setEnabled(true);
gridButtonOwner[i] = 0;
}
}
}
}
看看Java的wait()
和notify()
方法。 這是關於它們的教程。
可以使用以下功能暫停和恢復線程:
實現方式:
threadObject 。 暫停 ();
threadObject 。 簡歷 ();
但是我認為這些功能已被棄用。 雖然不確定。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.