本文共 2875 字,大约阅读时间需要 9 分钟。
为了解决多线程安全问题
在 Java 5.0 之前,协调共享对象的访问时可以使用的机制只有 synchronized 和 volatile 。Java 5.0 后增加了一些新的机制,但并不是一种替代内置锁的方法,而是当内置锁不适用时,作为一种可选择的高级功能。synchronized
jdk 1.5 后:同步锁 Lock 需要通过 lock() 方法上锁,必须通过 unlock() 方法进行释放锁。
ReentrantLock 实现了 Lock 接口,并提供了与synchronized 相同的互斥性和内存可见性。但相较于synchronized 提供了更高的处理锁的灵活性。Lock使用方式:
Lock lock = new ReentrantLock();lock.lock();try {} finally {lock.unlock();}
相关API:
不使用锁出现多线程安全问题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/