确认同步概念

时间:2016-10-02 04:08:43

标签: java multithreading synchronization

两类因素和加法

因子具有val变量,这意味着它在多个线程之间共享(在当前应用程序中我们使用两个线程)。

add class有一个add变量,它也在多个线程之间共享,因为它在factor类中实例化。

我的问题是

  1. 如果使用g = [[] for v in range(number_of_vertex)] for f,t,w in edges: g[f].append(Node(t,w)) g[t].append(Node(f,w)) ,则意味着两个线程中的任何一个都将锁定因子实例并递增val变量值,直到循环退出。 所以synchronized(this)在这里意味着我们不应该使用任何其他实例变量。我们只需要在synchronized块中使用factor instance的变量?

  2. 如果synchronized(this)在这里意味着我们只使用添加变量而不是因子实例类的val变量?

  3. 这个同步块存在很大的混乱。 我所理解的是同步块将锁定对象的实例并保护操作并使其线程安全。但是使用不同的实例真的意味着它应该只保护特定的实例变量而不是任何其他实例变量?

    synchronized(addition)

    Class Action& ConcurrentDoubt:

    class Factor implements Runnable
    {
    
    int val = 0;
    Addition addtion = new Addition();
    
    @Override
    public void run()
    {
    
        currInsLock();
        diffInsLock();
    }
    
    // locking on the current instance which is this
    // we will use synchronized(this)
    
    public void currInsLock() 
    {
        synchronized (this) 
        {
            for(int i=0;i<100;i++)
            {
                    try
                      {
                         Thread.sleep(100);
                      }
                    catch (InterruptedException e)
                    {
                          e.printStackTrace();
                    }   
            System.out.println(Thread.currentThread().getName()+"---val value lock on this obj -->"+val++);
    
            }
        }
    }
    
    
    
    // locking on the different instance
    public void diffInsLock() 
    {
        synchronized (addtion) 
        {
    
            for(int i=0;i<100;i++)
            {
                    try
                      {
                         Thread.sleep(100);
                      }
                    catch (InterruptedException e)
                    {
                          e.printStackTrace();
                    }   
            System.out.println(Thread.currentThread().getName()+"---val value lock on addition obj -->"+val++);
            System.out.println(Thread.currentThread().getName()+"---add value lock on addition obj -->"+addtion.add++);
            }
        }
    }
    
    }
    

2 个答案:

答案 0 :(得分:1)

没有。在特定对象上进行同步不会锁定该对象,也不会阻止您在synchronized块中使用其他对象。

在对象上进行同步可防止另一个线程同时尝试在同一对象上进行同步以进入同步块,直到第一个线程退出其同步块为止。由您决定如何同步访问某些可变状态。它可以是包含该状态或任何其他对象的对象。重要的是访问此可变状态的所有线程都使用相同的对象进行同步。

在发布的代码中,addtion.add可变状态得到了适当的保护,因为所有线程都在同一个对象addtion上同步,以便访问它。

val可变状态没有得到妥善保护,因为一个方法在this上同步以访问它,另一个方法在addtion上同步。因此,如果一个线程调用第一个方法而另一个调用第二个方法,则它们将尝试递增并同时读取相同的值。

答案 1 :(得分:0)

为了更好地理解同步概念,请阅读synchronized methodsintrinsic locks

的oracle教程文章

synchronized`关键字适用于方法/代码块,不适用于变量。

  

synchronized(this)在这里意味着我们不应该使用任何其他实例变量。

那是错的。 synchronized(this)允许访问其中一个线程并保持其他节点等待。但与此同时,成员变量对象可以通过其他方法进行修改。

方法1:您获得了锁synchronized (this),但未修改成员变量:addition。您可以使用其他一些方法来修改addition对象的成员变量(valFactor)。

方法2:您已获得synchronized (addtion)的锁定。现在添加不能被其他线程修改,试图从该代码块访问添加变量。您使用了错误的addition来修改val,因为其他线程可以自由修改val变量(原始而不是对象)。

如果要保护变量( of object ),请同步该特定变量而不是整个对象。

在应用程序中定义精细粒度锁。

  

但是使用不同的实例真的意味着它应该只保护特定的实例变量而不是任何其他实例变量吗?

synchronized确保:对同一对象的两个同步方法的调用不可能进行交错。但是如果你有差异实例,这些实例可以独立修改数据,除非变量是static且方法是static synchronized

查看相关的SE问题:

What does 'synchronized' mean?

Synchronization vs Lock

Avoid synchronized(this) in Java?