我需要两个计数器像国际象棋时钟一样工作。第一个开始,第二个停止。当第二个开始时,第一个停止。与这两个计数器并行,我需要另一个永不停止的时钟。
我正在努力去做。我创建了两个计数器,它工作得很好,但是当我创建一个新的线程(总共3个线程),这将运行时钟,它会导致一些问题(同时增加两个计数器)。
这些问题是否与同步问题有关?为什么它正确地运行2线程,而不是三个?
//////////////////////////////// HOW THE OBJECTS ARE CREATED /////////////////////////
private Relogio relogioBranco, relogioPreto;
private RelogioGeral relogioGeral;
relogioBranco = new Relogio(relogioBrancoLabel);
relogioPreto = new Relogio(relogioPretoLabel);
relogioGeral= new RelogioGeral(relogioPretoLabel,menu);
new Thread(relogioBranco).start();
new Thread(relogioPreto).start();
new Thread(relogioGeral).start();
relogioBranco.rodarRelogio(false);
relogioPreto.rodarRelogio(false);
relogioGeral.rodarRelogio(true);
////////////////////////////////////// COUNTERS //////////////////////////////
// The clock will be used to autosave my game every 1 minute
package Janela;
import java.io.Serializable;
import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.JLabel;
public class Relogio implements Runnable, Serializable {
private volatile AtomicInteger segundo, minuto, hora;
private JLabel relogioLabel;
private boolean relogioRodando;
public Relogio(JLabel relogio) {
segundo = new AtomicInteger();
minuto = new AtomicInteger();
hora = new AtomicInteger();
minuto.set(0);
hora.set(0);
segundo.set(0);
minuto.set(0);
this.relogioLabel = relogio;
}
public void rodarRelogio(boolean rodar) {
relogioRodando = rodar;
}
@Override
public void run() {
try {
while (true) {
Thread.sleep(1000);
if (relogioRodando) {
segundo.incrementAndGet();
if (segundo.intValue() == 60) {
segundo.set(0);
minuto.incrementAndGet();
if (minuto.intValue() == 60) {
minuto.set(0);
hora.incrementAndGet();
if (hora.intValue() == 24) {
segundo.set(0);
minuto.set(0);
hora.set(0);
}
}
}
String tempo = String.format("%02d:%02d:%02d", hora.intValue(), minuto.intValue(), segundo.intValue());
relogioLabel.setText(tempo);
}
}
} catch (InterruptedException ie) {
System.out.println("EXCEÇÃO INTERRUPTED EXCEPTION");
}
}
}
///////////////////////////////////////////// CLOCK ///////////////////////////////////
package Janela;
import MesaTabuleiro.ArrayPecas;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
public class RelogioGeral implements Runnable, Serializable {
private volatile AtomicInteger segundo, minuto, hora;
private final JLabel relogioLabel;
private boolean relogioRodando;
public RelogioGeral(JLabel relogio, Menu menu) {
segundo = new AtomicInteger();
minuto = new AtomicInteger();
hora = new AtomicInteger();
segundo.set(0);
minuto.set(0);
hora.set(0);
this.relogioLabel = relogio;
}
public void rodarRelogio(boolean rodar) {
relogioRodando = rodar;
}
@Override
public void run() {
try {
while (true) {
Thread.sleep(1000);
if (relogioRodando) {
segundo.incrementAndGet();
if (segundo.intValue() == 60) {
segundo.set(0);
minuto.incrementAndGet();
if (minuto.intValue() == 60) {
minuto.set(0);
hora.incrementAndGet();
if (hora.intValue() == 24) {
segundo.set(0);
minuto.set(0);
hora.set(0);
}
}
}
String tempo = String.format("%02d:%02d:%02d", hora.intValue(), minuto.intValue(), segundo.intValue());
relogioLabel.setText(tempo);
if (minuto.intValue() %1 == 1) {
saveGame();
}
}
}
} catch (InterruptedException ie) {
System.out.println("EXCEÇÃO INTERRUPTED EXCEPTION");
}
}
public void saveGame() {
JOptionPane.showMessageDialog(null, " 1 Minuto de Partida. Salvando Jogo.");
FileOutputStream output;
ObjectOutputStream oos = null;
try {
output = new FileOutputStream("jogo.ser");
oos = new ObjectOutputStream(output);
oos.writeObject(ArrayPecas.getInst().getPecasPretas());
oos.writeObject(ArrayPecas.getInst().getPecasBrancas());
oos.writeObject(ArrayPecas.getInst().getxPerdePr());
oos.writeObject(ArrayPecas.getInst().getyPerdePr());
oos.writeObject(ArrayPecas.getInst().getxPerdeBr());
oos.writeObject(ArrayPecas.getInst().getyPerdeBr());
oos.writeObject(TelaMenuJogo.getTela().getXequeVsbl());
oos.writeObject(TelaMenuJogo.getTela().getXequeMateVsbl());
oos.writeObject(TelaMenuJogo.getTela().getHistoricoTxt());
oos.writeObject(TelaMenuJogo.getTela().getJaDesenhou());
oos.writeObject(TelaMenuJogo.getTela().getLinha());
oos.writeObject(TelaMenuJogo.getTela().getColuna());
oos.writeObject(TelaMenuJogo.getTela().getLinPecaSel());
oos.writeObject(TelaMenuJogo.getTela().getColPecaSel());
oos.writeObject(TelaMenuJogo.getTela().getQtdJogadas());
oos.writeObject(TelaMenuJogo.getTela().getJogador());
} catch (FileNotFoundException ex) {
JOptionPane.showMessageDialog(null, "Arquivo nao encontrado");
} catch (IOException ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(null, "Erro ao tentar gravar no arquivo de saida");
} finally {
if (oos != null) {
try {
oos.close();
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, "Erro ao fechar arquivo de saida");
}
}
}
}
}
我认为你传递给主时钟的标签和传递给其他时钟的标签是一样的:
relogioBranco = new Relogio(relogioBrancoLabel);
relogioPreto = new Relogio(relogioPretoLabel);
relogioGeral= new RelogioGeral(relogioPretoLabel,menu);
不应该有自己的标签吗?
我认为这个问题与并发无关。你只会得到并发问题,如果两个线程正在工作一个资源(例如线程a和线程b都读取相同的字段)。这里的情况并非如此。每个线程都有自己的变量/对象