同步方法和对象锁

时间:2019-02-02 20:38:28

标签: java multithreading synchronization

据我了解,每个对象在尝试访问同步方法时都会发生锁定。 这是我的代码(在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'设为静态并写成这个(在testsyn类中):

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

这将达到我期望的方式,并且输出之间不会发生冲突。例如,如果主线程首先进入了同步方法,那么另一个线程将不得不等到主线程完成该方法之后。

我在这里问的问题是此更改如何影响程序的行为?为什么?

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

  

因此,假设我的输出的第一行是:“ Main:0”。那   表示主线程已获取测试对象的密钥   取名为“ k”,对吗?比这怎么可能,其他线程我   创建后可以进入“ inc1”方法并打印输出   前主线程已完成它?

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

  

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

是的。 static变量属于声明它们的类。它们被所有实例共享。两个线程共享一个静态k,该静态main()在运行from sklearn.metrics import make_scorer, confusion_matrix from sklearn.model_selection import GridSearchCV clf = RandomForestClassifier() parameters = {'random_state': [0,10], 'n_estimators':[100, 200]} #RandomForest Parameters to be optimized scorer = make_scorer(confusion_matrix[0]/fraude_on_test) #Get the first object from confusion matrix (TN, meaning Fraud-Fraud) grid_obj = GridSearchCV(clf, parameters, scoring=scorer) grid_fit = grid_obj.fit(x_train, y_train) best_clf = grid_fit.best_estimator_ 之前已初始化,之后没有被修改。由于他们俩都在尝试运行同一个对象的同步方法 ,因此必须等到另一个方法完成。