1、synchronized
同步锁的用法。它可以在代码中使用,也可以用来修饰函数。它的特性是:同一时间内,只有一个拥有锁的线程才能运行。
synchronized (obj) { while (<condition does not hold>) obj.wait(); ... // Perform action appropriate to condition }
常用方法:
obj为锁对象。
obj.wait() :调用后,该线程会释放同步锁obj对象,并使进程处于等待状态。
obj.notify():调用后将唤醒等待obj锁对象的线程队列中的第一个线程。唤醒等待该锁的线程队列中的第一个线程,并且当前进程释未释放锁,得在当前线程中需调用wait释放锁,使当前进程等待,唤醒的线程才可以执行,否则就等待线程释放它等待的锁。
obj.notifyAll() :调用后唤醒等待obj对象的线程队列中的所有线程,谁得到了线程释放的锁谁就运行。
NOTE:notify 和notifyAll只是激活了线程,但线程还是得等到锁对象才能运行。若不激活wait()后线程阻塞了,它不会主动去获取锁,因此当没有线程占用锁时,若没激活线程仍然不会运行。
例如下面的例子,大于105的时候卖票,低于100的时候制票:
public class LockDemo { private static int ticketNumber = 103; private static final Object ticketLock = new Object(); public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(new SellTicket()); t1.start(); Thread t2 = new Thread(new MakeTicket()); t2.start(); // synchronized (ticketLock) { // while(true) // { // ticketLock.wait(); // System.out.println("dddddddddddddddddddddd"); // } // // } } static class SellTicket implements Runnable{ public void run() { synchronized (ticketLock) { while(true){ if(ticketNumber <= 100) { //少于100张票后就停止售票,制造票,这里wait()会是释放ticketLock锁对象,让制票线程启动 System.out.println("卖完票"); ticketLock.notify(); try { ticketLock.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { try { Thread.sleep(1000); } catch(Exception e) { } System.out.println("卖票"+ ticketNumber); ticketNumber--; } } } } } static class MakeTicket implements Runnable{ public void run() { synchronized (ticketLock) { while(true) { if(ticketNumber>=105) { System.out.println("制造好票"); ticketLock.notify(); try { ticketLock.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { try { Thread.sleep(1000); } catch(Exception e) { } System.out.println("制造票" + ticketNumber); ticketNumber++; } } } } } }