欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

java多线程 -- 同步鎖

发布时间:2023/12/31 编程问答 52 豆豆
生活随笔 收集整理的这篇文章主要介绍了 java多线程 -- 同步鎖 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

为了解决多线程安全问题
在 Java 5.0 之前,协调共享对象的访问时可以使用的机制只有 synchronized 和 volatile 。
Java 5.0 后增加了一些新的机制,但并不是一种替代内置锁的方法,而是当内置锁不适用时,作为一种可选择的高级功能。

隐式锁

synchronized

  • 同步代码块;
  • 同步方法。
  • 显示锁 Lock

    jdk 1.5 后:同步锁 Lock 需要通过 lock() 方法上锁,必须通过 unlock() 方法进行释放锁。
    ReentrantLock 实现了 Lock 接口,并提供了与synchronized 相同的互斥性和内存可见性。但相较于synchronized 提供了更高的处理锁的灵活性。

    Lock使用方式:

    Lock lock = new ReentrantLock(); lock.lock(); try { } finally { lock.unlock(); }

    相关API:

  • void lock() 获取锁。
  • void lockInterruptibly() 如果当前线程未被中断,则获取锁。
  • Condition newCondition() 返回绑定到此 Lock 实例的新 Condition 实例。
  • boolean tryLock() 仅在调用时锁为空闲状态才获取该锁。
  • boolean tryLock(long time, TimeUnit unit) 如果锁在给定的等待时间内空闲,并且当前线程未被中断,则获取锁。
  • void unlock()释放锁。
  • 不使用锁出现多线程安全问题demo:

    package com.company;public class TestLock {public static void main(String[] args) {Ticket ticket = new Ticket();new Thread(ticket, "1号窗口").start();new Thread(ticket, "2号窗口").start();new Thread(ticket, "3号窗口").start();}}class Ticket implements Runnable{private int tick = 100;@Overridepublic void run() {while(true){if(tick > 0){try {Thread.sleep(200);} catch (InterruptedException e) {}System.out.println(Thread.currentThread().getName() + " 完成售票,余票为:" + --tick);}}}}

    看出现的问题(截取结果中一部分):

    3号窗口 完成售票,余票为:10 1号窗口 完成售票,余票为:8 2号窗口 完成售票,余票为:8 3号窗口 完成售票,余票为:8 2号窗口 完成售票,余票为:7 1号窗口 完成售票,余票为:7 3号窗口 完成售票,余票为:7 1号窗口 完成售票,余票为:6 2号窗口 完成售票,余票为:5 3号窗口 完成售票,余票为:4 3号窗口 完成售票,余票为:3 1号窗口 完成售票,余票为:3 2号窗口 完成售票,余票为:3 3号窗口 完成售票,余票为:2 1号窗口 完成售票,余票为:0 2号窗口 完成售票,余票为:1

    现在我们用Lock来进行处理:

    package com.company;import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;public class TestLock {public static void main(String[] args) {Ticket ticket = new Ticket();new Thread(ticket, "1号窗口").start();new Thread(ticket, "2号窗口").start();new Thread(ticket, "3号窗口").start();}}class Ticket implements Runnable {private int tick = 100;private Lock lock = new ReentrantLock();@Overridepublic void run() {while (true) {try {lock.lock();if (tick > 0) {try {Thread.sleep(200);} catch (InterruptedException e) {}System.out.println(Thread.currentThread().getName() + " 完成售票,余票为:" + --tick);}} finally { lock.unlock();}}}}

    看下结果(当然也是一部分),很完美解决多线程安全问题:

    2号窗口 完成售票,余票为:20 2号窗口 完成售票,余票为:19 2号窗口 完成售票,余票为:18 2号窗口 完成售票,余票为:17 2号窗口 完成售票,余票为:16 2号窗口 完成售票,余票为:15 2号窗口 完成售票,余票为:14 2号窗口 完成售票,余票为:13 2号窗口 完成售票,余票为:12 2号窗口 完成售票,余票为:11 2号窗口 完成售票,余票为:10 2号窗口 完成售票,余票为:9 2号窗口 完成售票,余票为:8 2号窗口 完成售票,余票为:7 2号窗口 完成售票,余票为:6 2号窗口 完成售票,余票为:5 2号窗口 完成售票,余票为:4 2号窗口 完成售票,余票为:3 2号窗口 完成售票,余票为:2 2号窗口 完成售票,余票为:1 2号窗口 完成售票,余票为:0

     

    总结

    以上是生活随笔为你收集整理的java多线程 -- 同步鎖的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。