java - 我已声明为同步的保护方法,但它给出的输出似乎是该方法未同步

标签 java synchronized

我认为输出会是

lol(0) lol(1) lol(2) lol(3) lol(4) lol(5) lol(6) lol(7) lol(8) lol(9) LOL(0) 
LOL(1) LOL(2) LOL(3) LOL(4) LOL(5) LOL(6) LOL(7) LOL(8) LOL(9)

因为我已经同步了保护方法

但输出来了

lol(0) LOL(0) lol(1) LOL(1) LOL(2) lol(2) LOL(3) lol(3) lol(4) LOL(4) lol(5) 
LOL(5) LOL(6) lol(6) lol(7) LOL(7) lol(8) LOL(8) LOL(9) lol(9)

为什么会这样?

ThreadBare类:

class ThreadBare implements Runnable
{ 

    String msg;
    ThreadBare(String m)
    {
        msg=m;
    }

     public  synchronized  void  protect()  //synchronized
    {
        for(int i=0;i<10;i++)
        {
            System.out.print(" "+msg+"("+i+")");
            try
            {
                Thread.sleep(1000);
            }
            catch(InterruptedException ie)
            {
                System.out.println(ie);
            }
        }
    }

     public void run()
    {
        protect();
    }
}

MainBare类:

class MainBare
{

    public static void main(String args[ ] )
    {
        Thread t1=new Thread(new ThreadBare("lol"));

        Thread t2=new Thread(new ThreadBare("LOL"));

        t1.start();
        t2.start();

    }
}

最佳答案

正如您可以在https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html下阅读的那样,在方法上使用 synchronize 关键字将仅同步该对象的方法调用。由于您创建了两个对象 t1t2,因此它们彼此不同步。

您可以通过使用 protected 方法创建单个对象来解决此问题,该对象作为对 t1t2 的引用传递,其中 t1t2,然后调用thatObject.protect()

或者,您可以将 protect() 重构为静态,在这种情况下,同步将在类范围内进行。

说明:

在方法上使用synchronize关键字将在内部使用this/类实例进行同步。在静态方法上使用 synchronize 将改为使用 Class 实例进行同步,使其可以跨不同的对象实例工作。

关于java - 我已声明为同步的保护方法,但它给出的输出似乎是该方法未同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54808114/

相关文章:

java - 如何在JPA中保存外键实体

java - 有没有办法强制 Eclipse 自动重启远程调试(在监听模式下)?

java - 同步方法还是使用 spring @transactional?

Java多线程端口扫描器

java - 使用synchronized关键字和join()的输出差异

java - Hive UDF Run:在Hive中创建临时函数时出错

java - 排除和包含在 Maven 程序集插件中不起作用

java - JTextPane 中单词的居中对齐

Java 线程和同步块(synchronized block)

java - 'synchronized barriers' 是什么?