当前位置: 代码迷 >> 综合 >> Java_175_Thread_可重入锁_不可重入锁_synchronized不可中断_ReentrantLock可中断
  详细解决方案

Java_175_Thread_可重入锁_不可重入锁_synchronized不可中断_ReentrantLock可中断

热度:80   发布时间:2024-01-31 09:15:16.0

可重入锁

package TCPUDPThread;import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;/*** 可重入锁* 锁作为并发共享数据保证一致性的工具,大多数内置锁都是可重入的,也就是说,如果某个线程试图获取一个已经由它自己持有的锁时,那么这个请求会立刻成功,并且将这个锁的计数值加1,而当线程退出同步代码块时,计数器将会递减,当计数值等于0时,锁释放.* 如果没有可重入锁的支持,在第二次企图获得锁时将会进入死锁状态.可重入锁随处可见** 可重入锁,锁可以延续使用*/
/*** 可重入锁演示* @author pmc**/
public class synchronizedTest16 {public synchronized void a(){System.out.println("a()");}public synchronized void b(){System.out.println("b()");}/*** 可重入锁用法*/public synchronized void all(){a();b();}public static void main(String[] args) {new Thread(()->{//第一次获得锁synchronized(synchronizedTest16.class){while(true){System.out.println("1");//第二次获得同样的锁synchronized(synchronizedTest16.class){System.out.println("2");}try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}}).start();synchronizedTest16 t6=new synchronizedTest16();t6.all();}
}

不可重入改可重入/ReentrantLock 

package TCPUDPThread;import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;/*** 可重入锁* 锁作为并发共享数据保证一致性的工具,大多数内置锁都是可重入的,也就是说,如果某个线程试图获取一个已经由它自己持有的锁时,那么这个请求会立刻成功,并且将这个锁的计数值加1,而当线程退出同步代码块时,计数器将会递减,当计数值等于0时,锁释放.* 如果没有可重入锁的支持,在第二次企图获得锁时将会进入死锁状态.可重入锁随处可见** 可重入锁,锁可以延续使用*/
/*** 可重入锁演示* @author pmc**/
public class synchronizedTest15 {
//ReentrantLock lock=new ReentrantLock();ReLock lock=new ReLock();public void a() throws Exception{lock.lock();b();lock.unlock();}public void b() throws Exception{lock.lock();System.out.println("B");lock.unlock();}public static void main(String[] args) throws Exception {synchronizedTest15 test=new synchronizedTest15();test.a();}
}
/***//**改为重入锁代码* @author pmc**/
class ReLock{//是否占用private boolean isLockde=false;Thread locked=null;//存储线程**private int count=0;//**//使用锁public synchronized void lock() throws Exception{Thread t=Thread.currentThread();//**while(isLockde&&locked!=t){//**System.out.println(isLockde);System.out.println("1");wait();System.out.println("2");}isLockde=true;locked=t;//**count++;//**}//释放锁public synchronized void unlock(){if(Thread.currentThread()==locked){//**count--;//**if(count==0){//**isLockde=false;notify();locked=null;}}}
}

ReentrantLock常常对比着synchronized

(1)synchronized是独占锁,加锁和解锁的过程自动进行,易于操作,但不够灵活。ReentrantLock也是独占锁,加锁和解锁的过程需要手动进行,不易操作,但非常灵活。

(2)synchronized可重入,因为加锁和解锁自动进行,不必担心最后是否释放锁;ReentrantLock也可重入,但加锁和解锁需要手动进行,且次数需一样,否则其他线程无法获得锁。

(3)synchronized不可响应中断,一个线程获取不到锁就一直等着;ReentrantLock可以相应中断。

ReentrantLock好像比synchronized关键字没好太多,我们再去看看synchronized所没有的,一个最主要的就是ReentrantLock还可以实现公平锁机制。什么叫公平锁呢?也就是在锁上等待时间最长的线程将获得锁的使用权。通俗的理解就是谁排队时间最长谁先执行获取锁。

  相关解决方案