多线程案例产生的数据误差

xl_echo编辑整理,欢迎转载,转载请声明文章来源。更多IT、编程案例、资料请联系QQ:1280023003 百战不败,依不自称常胜,百败不颓,依能奋力前行。——这才是真正的堪称强大!!


需求:一个电影院售票站,总共有四个窗口,但是只有50张票,如何保证四个窗口售票的同时保证售票不出错。

分析:售票站就相当于一个进程,在进程当中有个四个线程(窗口),所以我们要四个窗口同时执行售票工作,那么我们的程序就需要四个线程。

代码示例:

package com.echo;

/**
 * @Author xl_echo
 * @Date 2018/8/7 下午1:54
 **/
public class Window extends Thread {

  //售票窗口
  private final String name;

  //有50张电影票
  private static final int MAXTicket = 50;

  public Window(String name) {
    this.name = name;
  }

  private int index = 1;

  @Override
  public void run(){
    while (index <= MAXTicket){
      System.out.println("窗口" + name + "当前是第" + (index++) + "张票");
    }
  }

  public static void main(String[] args) {
    Window window1= new Window("1号窗口");
    window1.start();
    Window window2= new Window("2号窗口");
    window2.start();
    Window window3= new Window("3号窗口");
    window3.start();
    Window window4= new Window("4号窗口");
    window4.start();
  }

}

根据我们之前的案例,我们需要四个窗口所以我们将Window类集成了Thread,然后每一个window对象,我们调用start来启动一个线程。使用四个线程执行售票,最后发现并没有实现我们想要的效果,输出如下:
这里写图片描述

实际输出的结果我这里只截取了一部分,但是也不难发现,有两个50,其实是每一个线程都从1执行到了50。如果对关键字掌握熟悉的朋友会发现,我们的index是没有被static修饰的。当我们的窗口实例化成功时,那么都会创建一个index,index不是共享数据,所以造成了我们的售票计数出现重复。当我们使用static修饰的时候会出现,index的叠加不会因为线程的增加而重复,我们的需求达到了

希望达到我们想要的效果,就要做如下改进

private static int index = 1;

改进后输出结果如下
这里写图片描述

分析:static是关键字,如果用static修饰的变量,将会被共享,在程序被加载的时候就已经创建出来了。

其实通过我们的改进,可以看出我们的输出结果暂时达到了我们的要求。不过如果我们的数据index增加到很大时,就会出现线程安全问题。所以当我们建议最好还是不要使用这种办法来解决,这里最好的解决办法是我们使用Runnable接口来完善这个问题。

猜你喜欢

转载自blog.csdn.net/xlecho/article/details/81481871
今日推荐