我正在尝试设置一个计时器线程,每秒一次递增计数器并将结果输出到终端。
public class SecondCounter implements Runnable
{
private volatile int counter;
private boolean active;
private Thread thread;
public SecondCounter()
{
counter = 0;
active = true;
thread = new Thread(this);
thread.start();
}
public int getCount()
{
return counter;
}
public void run()
{
while(active)
{
try {
Thread.sleep(1000);
} catch(InterruptedException ex) {ex.printStackTrace();}
synchronized(this)
{
System.out.print(++counter+" ");
try{
notifyAll();
wait();
} catch(InterruptedException ex) {ex.printStackTrace();}
}
}
}
然后,我在类中有一个名为messagePrinter()的方法,它接受一个整数,创建一个新线程,并监视主计时器线程以查看该int的多个是否在计数上:
public synchronized void messagePrinter(final int x)
{
Runnable mp = new Runnable()
{
public void run()
{
while(active)
{
synchronized(this)
{
try {
while(counter%x != 0 || counter == 0 )
{
notifyAll();
wait();
}
System.out.println("\n"+x+" second message");
notifyAll();
} catch(InterruptedException ex) {ex.printStackTrace();}
}
}
}
};
new Thread(mp).start();
}
我已经尝试过使用wait()和notifyAll(),但我尝试过的每个组合都会导致两个线程进入等待状态并导致死锁。或者,计时器线程将占用所有线程时间,并且永远不会给messagePrinter一个检查当前计数的机会。
输出应该是这样的:
1 2 3
3 second message
4 5 6
3 second message
我知道使用这种方法,计时器可能没有时间在每个刻度上完美的1秒,但练习的目的是获得在线程之间传递信息的一些经验。
这是我的主要文件:
public class Main2
{
public static void main(String[] args)
{
SecondCounter c = new SecondCounter();
c.messagePrinter(3);
}
}
任何有线程经验的人都会给我一些关于我哪里出错的见解?
编辑:我已将整数计数器转换为原子整数,并且我将messagePrinter更改为在“SecondCounter.this”而不是“this”上同步。它现在正在工作!无论如何,当有多个messagePrinters时,它正在打印“x second message”大约三十次循环。我想我可以解决这个问题。
答案 0 :(得分:0)
我现在正在使用它,这是我的工作代码:
import java.util.concurrent.atomic.AtomicInteger;
public class SecondCounter implements Runnable
{
private volatile AtomicInteger counter;
private boolean active;
private boolean printed;
private Thread thread;
public SecondCounter()
{
counter = new AtomicInteger(0);
active = true;
thread = new Thread(this);
thread.start();
}
public void run()
{
while(active)
{
try {
Thread.sleep(1000);
} catch(InterruptedException ex) {ex.printStackTrace();}
synchronized(this)
{
System.out.print(counter.incrementAndGet()+" ");
printed = false;
try{
this.notify();
this.wait();
} catch(InterruptedException ex) {ex.printStackTrace();}
}
}
}
public synchronized void messagePrinter(final int x)
{
Runnable mp = new Runnable()
{
public void run()
{
while(active)
{
synchronized(SecondCounter.this)
{
try {
while(counter.get()%x != 0 || counter.get() == 0 )
{
SecondCounter.this.notify();
SecondCounter.this.wait();
}
if(!printed)
{
System.out.println("\n"+x+" second message");
printed = true;
}
SecondCounter.this.notify();
SecondCounter.this.wait();
} catch(InterruptedException ex) {ex.printStackTrace();}
}
}
}
};
new Thread(mp).start();
}
}