• 线程问题——同步和死锁


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

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

    运行结果同上。

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

  • 相关阅读:
    Resample the mask
    高斯消元法
    java中的大数BigInteger
    JAVA中如何使用SORT从大到小排
    Java中Array.sort()的几种用法简明教程 (需要初始化要排序的对象)
    java中两个字符串如何比较大小
    java数组初始化函数
    BestCoder Round #89 Fxx and string
    Flooded!
    基础练习 数列排序
  • 原文地址:https://www.cnblogs.com/lnluckybamboo/p/3951305.html
Copyright © 2020-2023  润新知