线程问题——同步和死锁

【问题引出】:比如说对于买票系统,有下面的代码:

 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
4
3
2
1
0
-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--);
        }
    }

运行结果同上。

提醒一下,当多个线程共享一个资源的时候需要进行同步,但是过多的同步可能导致死锁

 

posted @ 2014-09-02 13:45  小豆灵师  阅读(117)  评论(0编辑  收藏  举报