本帖最后由 安显杰 于 2012-10-25 19:43 编辑
一个Java程序的多线程之间可以共享数据。当线程以独立的异步方式访问共享数据时,有时候是不安全的或者不符合逻辑的。
比如,两个线程同时存取一个数据流,其中一个对数据进行了修改,而另一个线程仍旧是修改前的数据,这就带来了数据不一致的问题。
1用Java语言的关键字synchronized实现对共享数据同步线程同步是多线程编程的一个重要的技术。
例如模拟一个火车票售票系统,有100张票分别由4个线程完成。importjava.io.
*;classticket//主类{publicstaticvoidmain(Stringargs[])
{SellThreadst=newSellThread();newThread(st).start();
newThread(st).start();newThread(st).start();newThread(st).start();}}
classSellThreadimplementsRunnable{inttickets=100;//总票数publicvoidrun()
{while(true){if(tickets>0){try{Thread.sleep(10);//当前正在执行线程睡眠一会}catch(Exceptione){e.printStackTrace();}System.out.println(Thread.currentThread()
.getName()+"Sell-tickets:"+tickets);tickets--;}}}}
当还剩一张票时,tickets为1时,第一个线程进入if语句中,买了最后一张票,tickets为0,
这是时间片到期了;第二个线程开始运行,买了第0张票,tickets为-1,时间片到期了;
第3个线程进入if语句中,买了第-1张票,tickets为-2,时间片到期;第4个线程进入if语句中,买了第-2张票
,tickets为-3,时间片到期,这种结果是不正确的,像这类错误很难找出原因,在编程时应尽量避免,
这个问题发生主要是因为多个线程同时访问了tick-ets变量。可以采用多线程同步控制机制实现。
在同步机制中,不允许多线程并发执行,同步机制中不允许其他线程并发执行的程序代码段称为临界区,
此程序中if语句体称为临界区,将这段代码用同步来实现。同步有同步块和同步方法
,都是通过synchronized关键字来完成。对同步块而言,在synchronized后加上一个对象,
可以是this对象,这样实现了同步。这时程序执行结果是正确的。将上面程序加上同步块修改importjava.io.*;
classFirstThreadextendsThread//通过Thread类的子类创建的线程{//定义线程的run()
方法publicvoidrun(){System.out.println("FirstThreadisrunning…");}}
classSecondThreadimplementsRunnable//通过Runnable接口创建另一个线程{publicvoidrun()
{System.out.println("SecondThreadisrun-ning…");}}
classMulti_Thread{publicstaticvoidmain(Stringargs[])
//声明主方法{FirstThreadt1=newFirstThread();
//用Thread类的子类创建线程Threadt2=newThread(newSecondThread());
//用Runnable接口类的对象创建线程t1.start();t2.start();//启动线程} |