卖票问题通常被用来举例说明线程同步问题,在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修饰,也可以实现线程同步。