Java多线程混淆

时间:2015-05-14 11:31:01

标签: java multithreading synchronize

代码示例1:

namespace DummyNameSpace
{

    public interface IViewModel<T>
    {
        T DataModelObject { get; set; }
        string Name { get; set; }
    }

    public class SomeDataModelObject
    {
        public string SomeProperty { get; set; }
    }

    public class ViewModelInstance : IViewModel<SomeDataModelObject> //There will be various ViewModels that implement IViewModel, all with different 'T' types.
    {
        //Some properties, commands, etc.
    }

    public class TheMainViewModel //won't implement IViewModel, as this will be used to control all the various other viewmodels.
    {

        public void MethodBeingCalled(object viewmodelinstance)
        {
            Type type = viewmodelinstance.GetType();
            var x = (viewmodelinstance as IViewModel<type>).DataModelObject = null; //Will do other things here.
        }
    }
}

代码示例2:

class Test {
    MyObj myObj = new MyObj();

    public void test() {
        // doing my other stuff
        synchronized (myObj) {
            // accessing myObj
        }
    }
}

代码示例3:

class Test {
    MyObj myObj = new MyObj();

    public void test() {
        synchronized (myObj) {
            // doing my other stuff

            // accessing myObj
        }
    }
}

我希望在上面的代码段中保持线程安全 myObj 。那么以上代码中的哪一个是更优选的,为什么呢?

4 个答案:

答案 0 :(得分:3)

代码示例1是合适的。 因为持有对象的锁定然后做一些其他的东西是不合适的。

答案 1 :(得分:1)

根据我在开源项目中看到的代码,第一个代码示例更好,因为当您不再需要对象时,您将其释放,以便其他线程可以访问它。

答案 2 :(得分:1)

您的所有示例都没有包含足够的信息。

数据在哪里?什么是不变量?何时/何处/线程如何访问数据?

“线程安全”在没有数据的情况下毫无意义。有状态类的文档通常会提供有关其方法如何推进实例状态的保证。 “线程安全”意味着即使许多线程调用这些方法,也会满足这些保证。但是如果这个类没有状态,或者没有这样的保证,那么“线程安全”就没有任何意义。

P.S。:代码样本1比其他代码具有一个重要优势:互斥体(即synchronized块)更小。根据经验,您希望您的互斥锁尽可能小。如果“我的其他东西”不关心受互斥锁保护的数据,那么它应该不会发生在互斥锁中,因为这会阻止其他线程访问数据,并且它会阻止它们没有用的原因。

PPS:@ Ordous评论的+1:无法知道某个对象的状态是否是线程安全的,除非你能看到每个代码块可以修改或检查状态。由于您的示例中myObj不是private,因此我们必须假设其他地方的代码可以修改或检查其状态。由于我们无法看到该代码,因此我们必须假设myObj 线程安全。

答案 3 :(得分:1)

对整个方法进行锁定(如果时间很长)非常昂贵。它不仅可以阻止整个威胁,还可以阻止不需要同步的代码。其次,有时您可能不会使用rsautl,在这种情况下,示例2和3会很糟糕。

简短:仅同步块的一部分,使用对象。您还可以在对象上使用rsautl来检查它的值,而不使用同步块。请记住锁定可能代价高昂

但是当你的方法足够短,或只包含myObj的代码时,那么使整个方法同步是一个很好的解决方案。

omyObj

请看这个singleton示例。

相关问题