首页 > 代码库 > Java线程同步(synchronized)——卖票问题

Java线程同步(synchronized)——卖票问题

  卖票问题通常被用来举例说明线程同步问题,在Java中,采用关键字synchronized关键字来解决线程同步的问题。

  Java任意类型的对象都有一个标志位,该标志位具有0,1两种状态,其开始状态为1,当某个线程执行了synchronized(object)语句后,object对象的标志位变为0状态,直到执行完整个synchronized语句中的代码块后,该对象的标志位又回到1状态。

  当一个线程执行到synchronized(object)语句的时候,先检查object对象的标志位,如果为0状态,表明已经有另外的线程正在执行synchronized包括的代码,那么这个线程将暂时阻塞,让出cpu资源,直到另外的线程执行完相关的同步代码,并将object对象的标志位变为1状态,这个线程等阻塞就取消,线程能继续运行,该线程又将object的标志位变为0状态,防止其他的线程再进入相关的同步代码块中。

  所以在代码中,对共享资源采用synchronized关键字,可以实现线程同步。

  代码如下:

package luxl;public class ThreadSynchronizationTest {    /**     * @param args     */    public static void main(String[] args) {        // TODO Auto-generated method stub                TicketSeller seller = new TicketSeller();        Thread t1 = new Thread(seller);        Thread t2 = new Thread(seller);        Thread t3 = new Thread(seller);                t1.start();        t2.start();        t3.start();    }}/** *  * @author Administrator * */class TicketSeller implements Runnable{    int ticket_num = 100;    @Override    public void run() {        // TODO Auto-generated method stub        while(true){            synchronized(this){                if(ticket_num > 0){                    try{                        Thread.sleep((int)Math.random()*2000);                    }catch(Exception e){                        e.printStackTrace();                    }                                        System.out.println(Thread.currentThread().getName() + " is sell the ticket " + ticket_num);                    ticket_num --;                }            }        }    }    }

  上面的代码是创建了一个TicketSeller对象,然后创建不同的线程,所以这里是通过synchronized(this)中的this对象来实现的互锁。如果是通过不同的runnable对象创建线程,仍要实现线程同步对某一个资源实现线程同步,可以在runnable对象中创建一个静态的object类成员变量A,通过synchronized(A)也可以实现线程同步。同样的,也可以通过将访问共享资源的类静态方法进行synchronized修饰,也可以实现线程同步。