线程安全加锁的代码块的实现
1:synchronized(同步的) 锁住代码块. 同步代码块
1 synchronized(对象){ // 对象锁. 一定要注意,这个对象是同一个对象.!!!!!! "abc" 2 //代码块 3 } 4 5 同一个时间片,只有一个线程来访问这个代码块.
2: synchronized 锁住方法,方法锁
1 public synchronized void meth(){ //同步方法. 2 3 } 4 5 多个线程来访问这个方法的时候, 同一个时间片,只有一个线程来访问这个方法
案例:一个车站有5个售票窗口,5号窗口正在售第1000张票,4号窗口正在售第999张票,3号窗口正在售第998张票……
1 package com.lv.study.pm.first; 2 3 //解决超卖 4 //解决负数 5 public class TicketDemoSy5 { 6 7 public static void main(String[] args) { 8 9 // 窗口 10 SellTicketThread4 s1 = new SellTicketThread4("窗口1"); 11 SellTicketThread4 s2 = new SellTicketThread4("窗口2"); 12 SellTicketThread4 s3 = new SellTicketThread4("窗口3"); 13 SellTicketThread4 s4 = new SellTicketThread4("窗口4"); 14 SellTicketThread4 s5 = new SellTicketThread4("窗口5"); 15 16 s1.start(); 17 s2.start(); 18 s3.start(); 19 s4.start(); 20 s5.start(); 21 22 } 23 24 } 25 26 class SellTicketThread4 extends Thread { 27 28 // 全局唯一 29 private static int ticketNumber = 1000; 30 31 private String name; 32 33 public SellTicketThread4(String name) { 34 super(); 35 this.setName(name); 36 } 37 38 public SellTicketThread4() { 39 40 } 41 42 // 执行要卖票的业务 43 public void run() { 44 45 while (ticketNumber > 0) { 46 47 //指定一个锁存储的对象 不是指定要锁的元素 48 synchronized ("n") { 49 50 //必须要判断一次来解决还有其他线程等着拿锁的情况 51 //就算拿到了锁 符合不了要求也进不来 52 if(ticketNumber>0){ 53 54 //同步代码块:同一个时间只有拿到锁线程能够访问 55 System.out.println(this.getName() + "开始卖第" + ticketNumber+"张票"); 56 ticketNumber--; 57 58 } 59 60 } 61 62 } 63 } 64 65 }