同步块和条件变量锁之间有什么区别?

时间:2013-10-18 14:50:30

标签: java multithreading synchronized

...
lock.lock()
try{
...
}
finally{
lock.unlock()}
...

我注意到这并不能确保绝对互斥,因为同步总是如此,那么两者之间究竟有什么区别呢?

 import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

    public class Guys extends Thread{



            public static void go()throws InterruptedException{

                final Lock lock = new ReentrantLock();



                lock.lock();
                try{



                System.out.println("global " + main.global);



                main.global = main.global + 100;
                }
                finally
                {


                lock.unlock();
                }


            }






        public void run(){

            try{



                for(int i = 0; i <1; i++)
                {
                    System.out.println(this);




                    go();



                }
            } catch(InterruptedException e)
            {
                System.out.println("Interrupted Exception caught");
            }

        }


    }

我的帖子共享一个资源。在这种情况下,只有同步工作。

2 个答案:

答案 0 :(得分:0)

synchronnized块是一些有用但不可自定义的方法,只授予一个线程可以访问关键代码块。让我们回顾一些lock对象,这些对象可以提供优于synchronized块的优势:

<击> Reenterability - 考虑递归内的同步块。你确定它没有失败吗?那里ReentrantLock会帮助你

ReadWrite locks - 假设您有一些Map的1000个读者,但只有1个编写者。如果读者可以同时阅读,则可以进行大的优化,但仅对作者进行锁定。然后使用ReadWriteLock try..finally为您带来巨大好处

答案 1 :(得分:0)

每次调用方法时都会创建一个新的Lock对象,因此每个线程都会锁定另一个对象。

取出这一行

final Lock lock = new ReentrantLock();

在方法之外,使其成为类成员,它应该正常工作。

@Edit:更深入的解释:

使方法同步可以通过锁定对象来保护它,就像您自己使用Lock对象一样。如果它是非静态方法,则锁定在“this”对象上完成。由于此处有静态方法,因此锁定将位于表示Guys类的对象上。有一个这样的对象,因此只能获得一个锁。如果一个线程持有锁,其他人必须等待。

你在这里做的是在每次调用go()方法时创建一个新的Lock对象,因此每个调用go()方法的线程都会获得一个不同的锁,它可以防止任何东西,因为只有那个线程可以调用lock.lock(在它上面(正如我所说的其他线程将在他们自己的Lock实例上调用lock())。

将此Lock变量从方法中取出并使其成为类变量将意味着调用go()方法的所有线程将尝试获取相同的锁 - 类似于synchronized所做的。

@ Edit2:更生动地展示它就像是有一群人,只有拿着棍子的人才会说话。当只有1个棒时(在同步方法或共享锁对象的情况下),一切正常。但显然当它是一群波兰人(编辑说明我是波兰语,所以我可以取笑我自己的人)时,每个人都会带着他们自己的棍子(这与你的新ReentrantLock()类似)。这将导致每个人同时说话。显然每个人都会像“omg但我有一根棍子,我现在有充分的权利发言!”。