关于多线程Runnable,Thread的多线程资源共享问题

关于多线程Runnable中的多线程资源共享问题

首先我们使用常用的卖票模型来进行模拟:

  • 继承Thread类

    • class Tick_Thread extends Thread{
          private int tickcount=5;
          public void run(){
              while(tickcount>0){
              System.out.println(Thread.currentThread().getName()+"正在卖票"+"剩余票数"+--tickcount);
              }
          }
      }
      
      public class Ticketsell_Thread {
      
          public static void main(String []args){
              Tick_Thread tq1=new Tick_Thread();
              tq1.setName("窗口1");
              Tick_Thread tq2=new Tick_Thread();
              tq2.setName("窗口2");
              Tick_Thread tq3=new Tick_Thread();
              tq3.setName("窗口3");
      
              tq1.start();
              tq2.start();
              tq3.start();
          }
      }
      
      /*output:
      窗口1正在卖票剩余票数4
      窗口2正在卖票剩余票数4
      窗口1正在卖票剩余票数3
      窗口1正在卖票剩余票数2
      窗口1正在卖票剩余票数1
      窗口3正在卖票剩余票数4
      窗口1正在卖票剩余票数0
      窗口2正在卖票剩余票数3
      窗口2正在卖票剩余票数2
      窗口2正在卖票剩余票数1
      窗口2正在卖票剩余票数0
      窗口3正在卖票剩余票数3
      窗口3正在卖票剩余票数2
      窗口3正在卖票剩余票数1
      窗口3正在卖票剩余票数0
      */
      

      这里可以看到总共卖出了15张票,明显是不对的,因为在我们每次都是new了一个新的Tick_Thread类,所以Tick_Thread中的成员变量tick_count每次都会被初始化为5,如果把变量tickcount设置为static全局变量,则不会出现多卖票的问题,这是因为static不会因为类的实例化而被初始化,当然可以通过设置够造方法的方式传入新的tick_count值,这样效果仍然与代码相同。

  • 实现Runnable接口

    • public class Ticketsell_Thread {
          public static void main(String []args){
              Tick_Runnable t1=new Tick_Runnable();
              Thread th1=new Thread(t1,"th1");
              Thread th2=new Thread(t1,"th2");
              Thread th3=new Thread(t1,"th3");
              
              th1.start();
              th2.start();
              th3.start();
          }
      }
      class Tick_Runnable implements Runnable{
          private int tickcount=5;
          public void run(){
              while(tickcount>0){
                  System.out.println(Thread.currentThread().getName()+"正在卖票"+"剩余票数"+--tickcount);  
              }
          }
      }
      /*output:
      th1正在卖票剩余票数4
      th1正在卖票剩余票数1
      th3正在卖票剩余票数2
      th2正在卖票剩余票数3
      th1正在卖票剩余票数0
      */
      

      使用实现Runnable似乎就不会出现多卖票的情况了,原因是因为,当我们在初始化线程的时候传入的都是同一个Runnable实现类,三个线程执行时也是共享同一类的资源,tickcount没有被再次初始化,

      如果创建新进程的时候代码如下:

      Thread th1=new Thread(new Tick_Runnable(),"th1");
      Thread th2=new Thread(new Tick_Runnable(),"th2");
      Thread th3=new Thread(new Tick_Runnable(),"th3");
      

      则输出结果与第一种方式一致。当然,在这种情况下将tickcount设置为static属性,则仍然可以正常卖票。

  • 总结:所以资源共享,资源冲突问题,实质上是成员变量的属性问题。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容