Java 计时器死锁问题

Java 计时器死锁问题,java,multithreading,timer,Java,Multithreading,Timer,我试图设置一个计时器线程,每秒递增一个计数器,并将结果输出到终端 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)

我试图设置一个计时器线程,每秒递增一个计数器,并将结果输出到终端

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();
}
我曾尝试过多次使用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”上同步。现在开始工作了!无论如何,当有多个MessagePrinter时,它一个循环打印大约30次“x秒消息”。不过我想我可以解决这个问题。

我现在可以用了,下面是我的工作代码:

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();
}

}

我现在正在工作,这是我的工作代码:

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();
}

}

将“count”对象转换为原子整数您的
synchronized
部分由不同的
对象同步。第一个使用
SecondCounter
的实例,第二个使用创建的
Runnable
的实例。我对java非常陌生,但我认为在第二种情况下应该使用
synchronized(SecondCounter.this)
(和
SecondCounter.wait
/
SecondCounter.notifyAll
),我会尝试一下,谢谢@你的建议似乎奏效了!不过,我需要调用
SecondCounter.this.wait
等。将“count”对象转换为原子整数您的
synchronized
部分由不同的
this
对象同步。第一个使用
SecondCounter
的实例,第二个使用创建的
Runnable
的实例。我对java非常陌生,但我认为在第二种情况下应该使用
synchronized(SecondCounter.this)
(和
SecondCounter.wait
/
SecondCounter.notifyAll
),我会尝试一下,谢谢@你的建议似乎奏效了!尽管如此,我还是需要调用
SecondCounter.this.wait
,等等。