繁体   English   中英

如何在java中使用synchronized方法实现线程同步?

[英]how to achieve synchronization of threads using synchronized method in java?

我无法在这里实现线程同步。我使用了同步方法“meth”她。 所以根据定义,一次只能输入一个线程并打印我想要的输出。 但这不会发生。 需要帮忙。 谢谢。

class ABC {

    synchronized public void meth(String msg) {
        System.out.print("[" + msg);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            System.out.println(Thread.currentThread().getName() + " Thread Interrupted");
        }
        System.out.println("]");
    }
}

class SyncMethod implements Runnable {

    ABC a = new ABC();
    Thread t;

    SyncMethod(String s) {
        t = new Thread(this, s);
        t.start();
    }

    public void run() {
        a.meth(t.getName());
    }

    public static void main(String args[]) {
        new SyncMethod("Hello");
        new SyncMethod("Synchronized");
        new SyncMethod("World");
    }
}

电流输出:

        [Hello [Synchronized [World] ] ] ]

期望的输出:

        [Hello]
        [Synchronized]
        [World]

在实例方法上同步时:

class ABC
{
    synchronized public void meth(String msg)
    { ... }
}

这与:

class ABC
{
    public void meth(String msg) {
        synchronized (this) { ... }
    }
}

即您正在获取的监视器是该类的实例 但是你要创建3个独立的实例(每个线程调用new ABC() ),并分别在每个实例上获取监视器,因此同步实际上是无操作。

您需要在公共对象上进行同步。 例如:

class ABC
{
    public void meth(String msg) {
        synchronized (ABC.class) { ... }
    }
}

通常,在类上进行同步是不明智的,因为程序中任何位置的任何代码都可以获取该监视器,因此您可能会遇到意外争用。

相反,传入一个锁定对象:

class ABC
{
    private final Object lock;

    ABC(Object lock) { this.lock = lock; }

    public void meth(String msg) {
        synchronized (lock) { ... }
    }
}

并将相同的lock传递给您要同步的所有ABC实例。


但是,正如urag在他/她的回答中指出的那样 ,您可以将相同的ABC实例传递给所有线程,而不是在每个SyncMethod创建新实例。 有时最简单的解决方案在我写答案时就逃过了我;)

看看你每次调用SyncMethod的构造函数时都在创建新的ABC实例,所以你有3个类的副本,每个副本都由不同的线程调用,所以它们不竞争监视器所以你需要的是使用相同的ABC对象这里所有3个电话都是解决方案

class SyncMethod implements Runnable {
Thread t;
ABC a;

SyncMethod(String s, ABC a) {
    this.a = a;
    t = new Thread(this, s);
    t.start();

}

public void run() {
    a.meth(t.getName());
}

public static void main(String args[]) {
    ABC a = new ABC();
    new SyncMethod("Hello", a);
    new SyncMethod("Synchronized", a);
    new SyncMethod("World", a);
}

}

我自己带来了更好的解决方案。 正如@urag所说,当我创建一个新的对象evrytime时,我们需要一个对象来调用synchronized方法,从而调用3个同步方法。 我们可以使ABC类的对象静态,因此它不会重新生成自己,代码也会变短。我检查了这个工作。

    class ABC
{
    synchronized public void meth(String msg)
    {
        System.out.print("[" + msg);
        try
        {
            Thread.sleep(1000);
        }
        catch(InterruptedException e)
        {
            System.out.println(Thread.currentThread().getName() + " Thread Interrupted");
        }
        System.out.println("]");
    }
}
class SyncMethod implements Runnable
{
    static ABC a = new ABC();
    Thread t;
    SyncMethod(String s)
    {
        t= new Thread(this,s);
        t.start();
    }
    public void run()
    {
        a.meth(t.getName());
    }
    public static void main(String args[])
    {
        //ABC a = new ABC();
        new SyncMethod("Hello");
        new SyncMethod("World");
        new SyncMethod("Synchronized");
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM