synchronized和Lock复习

时间:2023-03-09 07:54:27
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();

}

   }

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