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

protect method I have declared as synchronized but output that it gives seems to be that the method is not 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:

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:

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,因此它们彼此不同步。

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

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

解释:

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