zoukankan      html  css  js  c++  java
  • 线程问题——同步和死锁

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

     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--);
            }
        }

    运行结果同上。

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

  • 相关阅读:
    Codeforces 67A【模拟】
    Codeforces325 D【并查集维护连通性】
    CodeForces 363D 【二分+贪心】
    Lightoj1084【DP啊DP】
    lightoj1062【几何(二分)】
    lightoj1066【BFS】
    lightoj1064 【DP求方案】
    lightoj1063【求割点】
    lightoj 1074【spfa判负环】
    CodeForces 382C【模拟】
  • 原文地址:https://www.cnblogs.com/lnluckybamboo/p/3951305.html
Copyright © 2011-2022 走看看