package com.yonyou.sci.gateway.exec; public class SellTicket implements Runnable{ private static int ticket = 1; @Override public void run () { while (true) { if (ticket > 0) { try{ // 模拟在这个位置,线程的执行权限被其他线程抢走了 Thread.sleep(10); }catch (Exception ex){} System.out.println(Thread.currentThread().getName()+" 出售第 " + ticket-- +" 票"); } } } }
package com.yonyou.sci.gateway.exec; public class SellMain { public static void main (String[] args) { SellTicket st = new SellTicket(); Thread t1 = new Thread(st); Thread t2 = new Thread(st); Thread t3 = new Thread(st); t1.start();t2.start();t3.start(); } }
结果:
Thread-0 出售第 1 票
Thread-2 出售第 0 票
Thread-1 出售第 -1 票
备注:线程的执行并不是按照顺序执行的,哪个线程抢到CPU执行权限,就执行哪个线程,所以上面的线程名不是按照顺序的。
1.Thread-0 抢到CPU执行权限、开始执行任务,判断剩余票数大于0,sleep后、线程Thread-1 开始执行;
2.Thread-2 抢到CPU执行权限、开始执行任务,Thread-0 还没有运行到 ticket-- 代码,此时 ticket 还是为1,判断剩余票数大于0,sleep后、线程Thread-1 开始执行;
3.Thread-1 抢到CPU执行权限、开始执行任务,Thread-0、Thread-2 都还没有运行到 ticket-- 代码,此时 ticket 还是为1,判断剩余票数大于0,sleep后、线程Thread-0 开始执行 ticket-- 代码,输出:Thread-0 出售第 1 票;
4.Thread-2 开始执行 ticket-- 代码,此时 Thread-0 已经运行 ticket-- 代码,ticket变量值为0,所以输出:Thread-2 出售第 0 票;
5.Thread-1 开始执行 ticket-- 代码,此时 Thread-0、Thread-2 已经运行 ticket-- 代码,ticket变量值为 -1,所以输出:Thread-1 出售第 -1 票;
方法一:增加 synchronized 代码块;
方法二:在方法上增加 synchronized 关键字;
方法三:使用 lock 锁;
package com.yonyou.sci.gateway.exec; public class SellTicket implements Runnable{ private static int ticket = 1; @Override public void run () { while (true) { synchronized (this){ if (ticket > 0) { try{ // 模拟在这个位置,线程的执行权限被其他线程抢走了 Thread.sleep(10); }catch (Exception ex){} System.out.println(Thread.currentThread().getName()+" 出售第 " + ticket-- +" 票"); } } } } }
线程类:
package com.yonyou.sci.gateway.exec.lock; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class SellTicketLock implements Runnable{ private int ticket = 1; private Lock lock = new ReentrantLock(); @Override public void run () { while (true) { lock.lock(); try{ if (ticket > 0) { Thread.sleep(10); System.out.println(Thread.currentThread().getName()+" 出售第 " + ticket-- +" 票"); } }catch (Exception ex){ System.out.println(ex.getMessage()); }finally { lock.unlock(); } } } }
执行线程:
package com.yonyou.sci.gateway.exec.lock; public class SellLockMain { public static void main (String[] args) { SellTicketLock st = new SellTicketLock(); Thread t1 = new Thread(st); Thread t2 = new Thread(st); Thread t3 = new Thread(st); t1.start();t2.start();t3.start(); } }
原文:https://www.cnblogs.com/tangshengwei/p/11723649.html