synchronized和Lock复习

       刚学编程的时候,不懂得同步的概念,只认为程序按照自己写的顺序执行,

直到学到多线程,但当时理解同步问题,也只是面对临界资源需要加锁去控制,

解决一些,如生产消费的问题。但当时一直没考虑过,多线程的情况下,程序可

能会执行失败的,比如一个Integer变量,多线程去累加,所以同步很重要。

       涉及例子一共两个:

       https://github.com/xuezhankui/Test/blob/master/src/com/xzk/test/TestSynchronized.java

       https://github.com/xuezhankui/Test/blob/master/src/com/xzk/test/TestWaitNotifyMain.java

     基本原则:

               但实例多线程,锁有效。多class实例,同步无效,因为每个实例分别有锁。 

     1.sychronized

        基本用法是 synchronized(obj){   代码块 }

                        或者方法前加synchronized

       1) 代码块很好理解,在一个线程执行完之前,下一个线程会等在代码块外,其实是等待拿obj这个锁。

       2) 方法前缀,是以该class的实例作为锁,并不是该方法加锁

             经测试: 

                   1》.多个方法有synchronized前缀,一个线程调用时,即使另一个线程调用B方法,也许要等待拿到锁才可以。

                   2》.多个方法中,没有synchronized前缀的方法不会被阻塞

     2.Lock

       lock只是接口,实现的类有几个,我例子用的ReentrantLock,没有使用公平锁。

       基本用法: private ReentrantLock lock = new ReentrantLock();

       使用 上,  锁的时候 lock.lock(); 不过要记得释放, lock.unlock();  简单的方式是try里面lock,finally里面去做unlock。

       补充,有个Condition,可以搜一下,可作为条件去,支持wait和notify,只是方法名字不一样。

       

     3. 其他lock

        其他锁没怎么看,有个读写锁,基本原则是读锁和写锁分开,写的时候阻塞读,读的时候锁是共享的。有空的时候写写例子再补充

     4.wait notify

        wait是让当前线程进入等待队列, notify是唤醒一个线程,notifyAll是唤醒所有等待的,然后再竞争锁。如果关注顺序需要用队列。

        一般情况下,写法:

         synchronized(obj){

        while(true){

                  if(需要等待资源)

         obj.wait();

                  执行完成

                     obj.notifyAll();

                 }

   }

         特别注意:以上只是写法,并不是逻辑,写的时候要注意防止死锁,上面只是生产消费模式中其中一方大概写法。

猜你喜欢

转载自www.cnblogs.com/xuezhankui/p/10685956.html