1、复习synchronized
案例:
1、创建资源类,提供操作数据的方法
2、创建3个售票员线程,卖出30张票
class Ticket{private int ticket=30;public synchronized void saleTickets(){if(ticket>0){System.out.println(Thread.currentThread().getName()+"卖出:"+(ticket--)+"剩余:"+ticket);}}}public class SaleTicket {public static void main(String[] args) {Ticket ticket=new Ticket();new Thread(new Runnable() {@Overridepublic void run() {for(int i=0;i<40;i++) {ticket.saleTickets();}}},"售票员1").start();new Thread(new Runnable() {@Overridepublic void run() {for(int i=0;i<40;i++) {ticket.saleTickets();}}},"售票员2").start();new Thread(new Runnable() {@Overridepublic void run() {for(int i=0;i<40;i++) {ticket.saleTickets();}}},"售票员3").start();}}
2、使用Lock接口改写例子
注意:使用Lock需进行异常的处理
class LTicket{private int ticket=30;//创建可重入锁private final ReentrantLock lock=new ReentrantLock();public void lsaleTicket(){lock.lock();//避免在操作数据时出现异常导致锁无法释放try {if(ticket>0){System.out.println(Thread.currentThread().getName()+"卖出:"+(ticket--)+"剩余:"+ticket);}}finally {lock.unlock();}}}public class LSaleTickets {public static void main(String[] args) {LTicket ticket=new LTicket();new Thread(()->{for(int i=0;i<40;i++){ticket.lsaleTicket();}//native:start方法执行,线程不一定立刻创建,取决与硬件资源的状态},"售票员1").start();new Thread(()->{for(int i=0;i<40;i++){ticket.lsaleTicket();}},"售票员2").start();new Thread(()->{for(int i=0;i<40;i++){ticket.lsaleTicket();}},"售票员3").start();}}
3、synchronized与Lock的区别
- Lock 是一个接口,而 synchronized 是 Java 中的关键字,synchronized 是内置的语言实现;
2. synchronized 在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而 Lock 在发生异常时,如果没有主动通过 unLock()去释放锁,则很可能造成死锁现象,因此使用 Lock 时需要在 finally 块中释放锁;
3. Lock 可以让等待锁的线程响应中断,而 synchronized 却不行,使用synchronized 时,等待的线程会一直等待下去,不能够响应中断;
