用于解决多线程安全问题的方式:
1. 同步代码块 (隐式锁)
2. 同步方法(隐式锁)
3. 同步锁 Lock( jdk 1.5 后)
注意:是一个显示锁,需要通过 lock() 方法上锁,必须通过 unlock() 方法进行释放锁
下面举一个售票例子:
1)同步代码块
package com.lxj.juc; public class TestSync { public static void main(String[] args) { Ticket ticket = new Ticket(); new Thread(ticket).start(); new Thread(ticket).start(); new Thread(ticket).start(); } } class Ticket implements Runnable{ private int ticket = 100; @Override public void run() { while(true) { synchronized(this) { //this代表对当前对象上锁 if(ticket > 0) { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" : 购票成功,余票为:" + --ticket ); }else { break; } } } } }
运行结果: Thread-0 : 购票成功,余票为:99 Thread-0 : 购票成功,余票为:98 Thread-2 : 购票成功,余票为:97 ..... Thread-2 : 购票成功,余票为:7 Thread-0 : 购票成功,余票为:6 Thread-0 : 购票成功,余票为:5 Thread-1 : 购票成功,余票为:4 Thread-1 : 购票成功,余票为:3 Thread-0 : 购票成功,余票为:2 Thread-0 : 购票成功,余票为:1 Thread-2 : 购票成功,余票为:0
2)同步方法
package com.lxj.juc; public class TestSync { public static void main(String[] args) { Ticket ticket = new Ticket(); new Thread(ticket).start(); new Thread(ticket).start(); new Thread(ticket).start(); } } class Ticket implements Runnable { private int ticket = 100; @Override public void run() { while (true) { if (ticket > 0) { int i = purchase(); if(i == 0) { break; } }else { break; } } } private synchronized int purchase() { if (ticket > 0) { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " : 购票成功,余票为:" + --ticket); }else { return 0; } return 1; } }
运行结果: Thread-0 : 购票成功,余票为:99 Thread-0 : 购票成功,余票为:98 Thread-0 : 购票成功,余票为:97 Thread-2 : 购票成功,余票为:96 Thread-1 : 购票成功,余票为:95 .... Thread-1 : 购票成功,余票为:8 Thread-2 : 购票成功,余票为:7 Thread-2 : 购票成功,余票为:6 Thread-0 : 购票成功,余票为:5 Thread-0 : 购票成功,余票为:4 Thread-0 : 购票成功,余票为:3 Thread-2 : 购票成功,余票为:2 Thread-1 : 购票成功,余票为:1 Thread-2 : 购票成功,余票为:0
3)同步锁lock
package com.lxj.juc; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class TestSync { public static void main(String[] args) { Ticket ticket = new Ticket(); new Thread(ticket).start(); new Thread(ticket).start(); new Thread(ticket).start(); } } class Ticket implements Runnable { private int ticket = 100; private Lock lock = new ReentrantLock(); @Override public void run() { while (true) { lock.lock(); //上锁 try { if (ticket > 0) { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " : 购票成功,余票为:" + --ticket); }else { break; } } finally { lock.unlock(); //解锁 } } } }
运行结果: Thread-0 : 购票成功,余票为:99 Thread-1 : 购票成功,余票为:98 Thread-1 : 购票成功,余票为:97 Thread-1 : 购票成功,余票为:96 Thread-1 : 购票成功,余票为:95 Thread-2 : 购票成功,余票为:94 ...... Thread-0 : 购票成功,余票为:6 Thread-0 : 购票成功,余票为:5 Thread-1 : 购票成功,余票为:4 Thread-2 : 购票成功,余票为:3 Thread-2 : 购票成功,余票为:2 Thread-2 : 购票成功,余票为:1 Thread-2 : 购票成功,余票为:0
注意使用同步锁一定要记得关闭锁,放在try{}finally{}中。
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦