【问题标题】:Synchronized methods and object locks同步方法和对象锁
【发布时间】:2023-04-04 06:00:02
【问题描述】:

根据我的阅读和理解,每个对象在尝试访问同步方法时都会发生锁定。 这是我的代码(在 2 个不同的类文件中):

public class test {

 public synchronized void inc1( String who ) {

         for( int i = 0 ; i < 1500 ; i++ )
             System.out.println( who+": "+i );
 }
}



public class testsyn implements Runnable {

    test k = new test( );

    public static void main( String[ ] args )
    {

        new Thread( new testsyn( ) ).start( );

        new testsyn( ).doStuff( );

    }

    public void doStuff( ) { k.inc1( "Main" ); }

    public void run( )
    {
        k.inc1( "Thread" );
    }
}

假设我的输出的第一行是: “主要:0”。 这意味着主线程已经获取了名为“k”的测试对象的密钥,对吧? 我创建的另一个线程怎么可能在主线程完成之前进入“inc1”方法并打印输出?

我注意到这个问题发生在这个特定的模式中,但是如果我将“k”设为静态并改为写这个(在 testyn 类中):

public class testsyn implements Runnable {

    static test k = new test( );

    public static void main( String[ ] args )
    {

        new Thread( new testsyn( ) ).start( );

        k.inc1( "Main" );

    }


    public void run( )
    {
        k.inc1( "Thread" );
    }
}

这会按我预期的方式工作,并且输出之间不会发生冲突。例如,如果主线程首先进入了同步方法,那么其他线程将不得不等到主线程完成该方法。

我在这里要问的问题是这种变化如何影响程序的行为?为什么?

【问题讨论】:

  • 由于您没有显示意外输出的示例,因此很难看出您的问题。

标签: java multithreading synchronization


【解决方案1】:

是的,synchronized关键字用于获取锁;锁与对象实例相关联。您有两个 test 类的实例;一个给每个线程。所以没有争议。当k字段为静态时,线程间共享一个实例。

【讨论】:

  • 哦!我想我没有这样想过。谢谢!
【解决方案2】:

假设我的输出的第一行是:“Main : 0”。那 表示主线程已经获取了测试对象的key 命名为“k”,对吧?比其他线程我怎么可能 created 能够进入“inc1”方法并打印输出 在主线程完成之前?

你写“名为'k'的测试对象”就好像只有一个一样。在您的示例中,k 是类testsyn 的实例变量,因此每个实例都有自己的。它们指的是不同的对象,每个对象都有自己的监视器。因此,执行其中一个对象的同步实例方法的线程不会阻止另一个线程执行另一个对象的同步实例方法。

如果我将“k”设为静态 [...],输出之间就不会发生冲突。

是的。 static 变量属于声明它们的类。它们由所有实例共享。一个静态的k,在main() 运行之前已经被初始化并且之后没有被修改,由你的两个线程共享。由于他们都试图运行同一对象的同步方法,因此必须等到另一个完成。

【讨论】:

    猜你喜欢
    • 2011-03-04
    • 2013-04-25
    • 1970-01-01
    • 2010-10-01
    • 2012-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多