Java 在';s使用了两个计数器和一个时钟,它们都在不同的线程中工作?
我需要两个计数器像国际象棋时钟一样工作。第一个启动时,第二个停止。当第二个开始时,第一个停止。 与这两个计数器并行,我需要另一个永不停止的时钟 我正试着去做。我创建了两个计数器,工作正常,但当我创建一个新线程(总共3个线程)来运行时钟时,它会导致一些问题(同时增加两个计数器) 这些问题是否与同步问题有关?为什么它可以正确地运行2个线程而不能运行3个线程Java 在';s使用了两个计数器和一个时钟,它们都在不同的线程中工作?,java,multithreading,counter,clock,Java,Multithreading,Counter,Clock,我需要两个计数器像国际象棋时钟一样工作。第一个启动时,第二个停止。当第二个开始时,第一个停止。 与这两个计数器并行,我需要另一个永不停止的时钟 我正试着去做。我创建了两个计数器,工作正常,但当我创建一个新线程(总共3个线程)来运行时钟时,它会导致一些问题(同时增加两个计数器) 这些问题是否与同步问题有关?为什么它可以正确地运行2个线程而不能运行3个线程 //////////////////////////////// HOW THE OBJECTS ARE CREATED ///////////
//////////////////////////////// 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都在读取同一个字段),才会出现并发问题。这里的情况并非如此。每个线程都处理自己的变量/对象。我认为两个计数器不需要两个线程。相反,您可以有一个线程交替迭代计数器。