博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java多线程 -- 同步鎖
阅读量:6198 次
发布时间:2019-06-21

本文共 2875 字,大约阅读时间需要 9 分钟。

为了解决多线程安全问题

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

隐式锁

synchronized

  1. 同步代码块;
  2. 同步方法。

显示锁 Lock

jdk 1.5 后:同步锁 Lock 需要通过 lock() 方法上锁,必须通过 unlock() 方法进行释放锁。

ReentrantLock 实现了 Lock 接口,并提供了与synchronized 相同的互斥性和内存可见性。但相较于synchronized 提供了更高的处理锁的灵活性。

Lock使用方式:

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

相关API:

  1. void lock() 获取锁。
  2. void lockInterruptibly() 如果当前线程未被中断,则获取锁。
  3. Condition newCondition() 返回绑定到此 Lock 实例的新 Condition 实例。
  4. boolean tryLock() 仅在调用时锁为空闲状态才获取该锁。
  5. boolean tryLock(long time, TimeUnit unit) 如果锁在给定的等待时间内空闲,并且当前线程未被中断,则获取锁。
  6. 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;    @Override    public void run() {        while(true){            if(tick > 0){                try {                    Thread.sleep(200);                } catch (InterruptedException e) {                }                System.out.println(Thread.currentThread().getName() + " 完成售票,余票为:" + --tick);            }        }    }}

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

3号窗口 完成售票,余票为:101号窗口 完成售票,余票为:82号窗口 完成售票,余票为:83号窗口 完成售票,余票为:82号窗口 完成售票,余票为:71号窗口 完成售票,余票为:73号窗口 完成售票,余票为:71号窗口 完成售票,余票为:62号窗口 完成售票,余票为:53号窗口 完成售票,余票为:43号窗口 完成售票,余票为:31号窗口 完成售票,余票为:32号窗口 完成售票,余票为:33号窗口 完成售票,余票为:21号窗口 完成售票,余票为:02号窗口 完成售票,余票为: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();    @Override    public 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号窗口 完成售票,余票为:202号窗口 完成售票,余票为:192号窗口 完成售票,余票为:182号窗口 完成售票,余票为:172号窗口 完成售票,余票为:162号窗口 完成售票,余票为:152号窗口 完成售票,余票为:142号窗口 完成售票,余票为:132号窗口 完成售票,余票为:122号窗口 完成售票,余票为:112号窗口 完成售票,余票为:102号窗口 完成售票,余票为:92号窗口 完成售票,余票为:82号窗口 完成售票,余票为:72号窗口 完成售票,余票为:62号窗口 完成售票,余票为:52号窗口 完成售票,余票为:42号窗口 完成售票,余票为:32号窗口 完成售票,余票为:22号窗口 完成售票,余票为:12号窗口 完成售票,余票为:0

 

转载地址:http://pmnca.baihongyu.com/

你可能感兴趣的文章
16进制整数转化成字符串
查看>>
这些年做LAMP的几点感悟——张东进
查看>>
git_git学习笔记
查看>>
查看QQ同时在线人数,分布
查看>>
MPFlipViewController
查看>>
发布一个库到CocoaPods
查看>>
java.util.Scanner
查看>>
开源 java CMS - FreeCMS2.6 数据库信息采集
查看>>
类和动态内存分配
查看>>
数组的全排列
查看>>
Extjs 3.2 EXT中的AJAX
查看>>
ContentResolver类
查看>>
Spring 中 redis 使用
查看>>
java.lang.OutOfMemoryError: Java heap space 解决方法
查看>>
CentOS6.0 x64 位将光盘作为yum源
查看>>
ubuntu 14.04 root用户登录
查看>>
MySQL性能优化的最佳20+条经验
查看>>
为什么使用Erlang?
查看>>
CodeIgniter Disallowed Key Characters
查看>>
浅谈iPhone OS(iOS)架构
查看>>