JavaSE---多线程(三)

死锁

  • 多个线程一起占有共享资源,并且都在等待其他线程释放资源,你等我,我等你,某一个同步块同时拥有两个以上对象的锁时,就可能会发生死锁问题。
  • 产生死锁的必要条件:
  1. 互斥条件:一个资源每次只能被一个进程使用。
  2. 请求和保持条件:一个进程因请求资源而阻塞时,对方获得的资源保持不放。
  3. 不剥夺条件:进程已获得资源,在未使用完之前,不能强行剥夺。
  4. 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
  • 我们只要想办法破坏其中一个条件就可以避免死锁。

Lock锁

  • JDK1.5之后出来,提供了更强大的线程同步机制—通过显示定义同步锁对象来实现同步,同步锁使用Lock对象充当。
  • java.util.concurrent.locks.lock接口是控制多个线程对共享资源进行访问的工具。锁提供了对共享资源的独占访问,每次只能有一个线程对Lock对象加锁,线程开始访问共享资源之前要先获得Lock对象。
  • ReentrantLock类实现了Lock,他拥有与synchronized相同的并发性和内存语义,在实现线程安全控制中,比较常用的是ReentrantLock可以显示的加锁,释放锁。

在这里插入图片描述

synchronized与lock的区别

  • Lock是显示锁(手动开启和关闭锁,别忘记关闭锁)synchronized是隐式锁,出了作用域自动释放。
  • Lock只有代码快锁,synchronized有代码块锁和方法锁。
  • 使用Lock锁,JVM将花费较少的时间来调度线程,性能更好,并且具有更好的扩展性(提供更多的子类)
  • 优先使用顺序:

Lock----同步代码块(已经进入了方法体,分配了相应资源)----同步方法(在方法体之外)

生产者消费者问题

  • 生产者和消费者共享同一个资源,二者之间互相依赖。互为条件。
  1. 对于生产者,没有生产产品之前,要通知消费者等待,生产好了之后,要立马通知消费者来取,
  2. 对于消费者,在消费之后,要通知生产者已经结束消费,需要生产新的产品以供消费。
  3. 在生产者消费者问题中,仅仅有synchronized是不够的

synchronized可阻止并发更新同一个共享资源,实现了同步。
synchronized不能用来实现不同线程之间的消息传递(通信)

在这里插入图片描述

管程法

在这里插入图片描述

信号灯法

线程池

  • 经常创建和销毁的,使用量特别大的资源,比如并发情况下的线程,对性能影响很大,
  • 提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中,可以避免频繁创建和销毁,实现重复利用,类似生活中的交通工具。
  • 使用线程池的好处:
  1. 提高响应速度(减少了创建线程的时间)。
  2. 降低资源消耗(重复利用线程池中的线程,不需要每次都创建)
  3. 便于线程管理:corePoolSize:核心池的大小,maximumPoolSize:最大线程数,KeepAliveTime:线程没有任务时,最多保持多长时间后会终止。

猜你喜欢

转载自blog.csdn.net/weixin_44861399/article/details/106533005
今日推荐