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

        }


    }

我的线程共享一个资源。在这种情况下,只有同步有效。

4

2 回答 2

0

synchronnized块是一些有用但不可自定义的方式来授予只有一个线程可以访问关键代码块。让我们回顾一些lock比同步块更有优势的对象:

可重入性- 考虑递归内部的同步块。你确定它没有失败?那里ReentrantLock会帮助你

读写锁- 假设您有 1000 名读者到某些地图,但只有 1 名作家。如果读者可以同时读取,则可以进行大优化,但仅对写入者进行锁定。然后try..finallyReadWriteLock给你带来很大的好处

于 2013-10-18T15:02:39.413 回答
0

您在每次调用该方法时创建一个新的 Lock 对象,因此每个线程都锁定在不同的对象上。

取出这条线

final Lock lock = new ReentrantLock();

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

@Edit:好的更深入的解释:

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

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

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

@Edit2:为了更形象地表现,就像有一群人,只有拿着棍子的人才能说话。当只有 1 根棍子时一切正常(同步方法或共享 Lock 对象就是这种情况)。但很明显,当它是一群波兰人时(编者注:我是波兰人,所以我可以取笑我自己的人)每个人都会带着他们自己的棍子(这与你的新 ReentrantLock() 类似)。这将导致每个人同时发言。显然每个人都会像“天哪,但我有一根棍子,我现在有完全的发言权!”。

于 2013-10-18T15:13:13.287 回答