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


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

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

    运行结果同上。

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

  • 相关阅读:
    【转】centos7关闭图形界面启动系统
    回顾测试入行以来的一些感受,浅谈对测试管理方面一些见解
    linux安装完全踩坑手册
    selenium 自动化测试个人总结(一)
    性能测试之数据库篇-查询(五 补充)
    性能测试之数据库篇-查询(四)
    性能测试之数据库篇-查询(三)
    性能测试之数据库篇-查询(二)
    性能测试之数据库篇-查询(一)
    性能测试之数据库篇-查询
  • 原文地址:https://www.cnblogs.com/lnluckybamboo/p/3951305.html
Copyright © 2020-2023  润新知