【问题标题】:can i synchronize 2 different methods? java我可以同步两种不同的方法吗?爪哇
【发布时间】:2015-03-19 21:28:18
【问题描述】:

我在 java 中使用 synchronized 关键字时遇到了一些麻烦。我确实了解线程锁定方法或代码块的部分,但我不知道如何在以下示例中使用它。

我有 2 个不同的线程(线程 A 和 Thead B)和一个 Class1,其中包含一个包含 Class2 实例的列表。 threadA 调用的 Class1.methodA() 修改列表中的信息。 threadB 调用的 Class1.methodB() 只使用列表中的信息。

我的结论是,当线程 A 正在修改列表中的数据而线程 B 正在使用它时,我的程序中就会出现问题。

我是否应该在 Class1 中创建一个同步方法,而不是调用 MethodA 或 MethodB(对我来说似乎是多余的)。或者线程能否只锁定正在修改的 Class2 的特定实例?

我很抱歉英语不好。

【问题讨论】:

    标签: java multithreading synchronization


    【解决方案1】:

    让两种方法在列表中同步:

    methodA()
    {
       synchronized(list) 
       {
          ... use the list, no one else can touch it
       }
       ... do other stuff.
    }
    

    methodB() 也一样

    More info here.

    【讨论】:

    • 谢谢。那么线程确实获得了列表上的锁而不是代码块上的锁?
    • 是的。在这种情况下,您不必担心两个线程调用同一个方法,而是两个方法访问同一个共享变量。
    【解决方案2】:

    关于线程有一个解释here

    好吧,回到你的问题。实际上,您可以只使用列表上的同步并在此同步块中进行读取或添加。

    synchronized(yourList)
    {
        // do something
    }
    

    否则我猜你可以使用java.util.concurrent 包中的CopyOnWriteArrayList (API)。但这确实很昂贵,因为它总是会生成底层数组的新副本。

    CopyOnWriteArrayList<String> myArrayList = new CopyOnWriteArrayList<String>();
    
    myArrayList .add("Stackoverflow");
    
    Iterator<String> iterator = myArrayList .iterator(); 
    
    while (iterator.hasNext())
       System.out.println(iterator.next());
    }
    

    另一种方法是使用synchronizedList

    List list = Collections.synchronizedList(new ArrayList());
    
    synchronized(list) {
        Iterator i = list.iterator();
        while (i.hasNext())
            foo(i.next());
    }
    

    但是最后你仍然需要同步块。 add 和 remove 方法本身是原子和线程安全的,但遍历列表不是。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多