【问题引出】:比如说对于买票系统,有下面的代码:
1 class hello implements Runnable { 2 private static int count=5; 3 public void run() { 4 for(int i=0;i<10;++i){ 5 if(count>0){ 6 try{ 7 Thread.sleep(1000); 8 }catch(InterruptedException e){ 9 e.printStackTrace();10 }11 System.out.println(count--);12 }13 }14 }15 16 public static void main(String[] args) {17 hello he=new hello();18 Thread h1=new Thread(he);19 Thread h2=new Thread(he);20 Thread h3=new Thread(he);21 h1.start();22 h2.start();23 h3.start();24 }25 }
【运行结果】
5
43210-1这里出现了-1,显然这个是错的。,应该票数不能为负值。
如果想解决这种问题,就需要使用同步。所谓同步就是在统一时间段中只有有一个线程运行,
其他的线程必须等到这个线程结束之后才能继续执行。
【使用线程同步解决问题】
采用同步的话,可以使用同步代码块和同步方法两种来完成。
(一)同步代码块
语法格式:
synchronized(同步对象){
//需要同步的代码
}
但是一般都把当前对象this作为同步对象。
比如对于上面的买票的问题,如下(修改run方法):
public void run() { for(int i=0;i<10;++i){ synchronized(this){ if(count>0){ try{ Thread.sleep(1000); }catch(InterruptedException e){ e.printStackTrace(); } System.out.println(count--); } } } }
【运行结果】:(每一秒输出一个结果)
5
4
3
2
1
(二)同步方法
语法格式为
synchronized 方法返回类型方法名(参数列表){
// 其他代码
}
修改run方法
public void run() { for (int i = 0; i < 10; ++i) { sale(); } } public synchronized void sale() { if (count > 0) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(count--); } }
运行结果同上。
提醒一下,当多个线程共享一个资源的时候需要进行同步,但是过多的同步可能导致死锁。