Я пытаюсь настроить поток таймера, который через секунду увеличивает счетчик и выводит результат на терминал.Timer Deadlock Issue
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(), который принимает в целом, создает новый поток, и контролирует основной поток таймера, чтобы увидеть, когда кратна этой ИНТ на счете:
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();
}
Я пытался возиться с ожиданием() и notifyAll() совсем немного, но каждый комбинации я попытался результаты в обоих потоков, входящих в состояние ожидания и вызывая затор. Или, поток таймера запустит все время потока и никогда не даст сообщениюPrinter возможность проверить, что подсчитывает в настоящее время.
Вот что результат должен выглядеть следующим образом:
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);
}
}
Любой с некоторым заправочным уходом опыта, чтобы дать мне некоторое представление о том, где я неправильно?
EDIT: Я преобразовал свой целочисленный счетчик в атомное целое число, и я изменил сообщениеPrinter для синхронизации на «SecondCounter.this» вместо «this». Теперь работает! В основном, в любом случае, он печатает «x second message» примерно тридцать раз, когда существует несколько MessagePrinters. Я думаю, что могу это исправить.
Преобразовать «считать» объект быть атомным числом –
Ваш 'раздел synchronized' синхронизируются различными' это 'объектов. Первый использует экземпляр «SecondCounter», второй использует экземпляр вашего созданного «Runnable». Я довольно новичок в java, но я думаю, что вы должны использовать 'synchronized (SecondCounter.this)' во втором случае (и 'SecondCounter.wait' /' SecondCounter.notifyAll'). –
Я дам вам попробовать, спасибо! – Araganor