• 关于练习线程的感想。


     

      我看了下别的大神的博客。结合自己的练习了下多线程的并发问题。我觉得就多线程而言。最重要的就是要把整个业务放进同步锁里面。

    synchronized这个关键字有两种用法1、放方法名前形成同步方法;2、放在块前构成同步块。


    比如:

    class thread4Test implements Runnable{
        private int ticket=10;
        public synchronized void run()
        {
            for(int i=1;i<50;i++)
            {
                if(ticket>0)
                {
                    //休眠1s秒中,为了使效果更明显,否则可能出不了效果
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"号窗口卖出"+this.ticket--+"号票");
                }
            }
        }
    }

    输出结果是

    a号窗口卖出10号票
    a号窗口卖出9号票
    a号窗口卖出8号票
    a号窗口卖出7号票
    a号窗口卖出6号票
    a号窗口卖出5号票
    a号窗口卖出4号票
    a号窗口卖出3号票
    a号窗口卖出2号票
    a号窗口卖出1号票

    这里的同步锁的位置是在run方法里面。同步的是run方法。这样的话启动一条线程之后就会一直运行。直到a执行完毕之后b再去执行的时候就没有票了。

    例如:

    class thread5Test implements Runnable{
      private int ticket=10;
      public void run()
      {
          for(int i=1;i<50;i++)
          {
             
              if(ticket>0)
              {
                  synchronized(this){
                  //休眠1s秒中,为了使效果更明显,否则可能出不了效果
                  try {
                      Thread.sleep(1000);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
                  System.out.println(Thread.currentThread().getName()+"号窗口卖出"+this.ticket--+"号票");
                  }
              }
          }
      }
    }

    执行结果:

    a号窗口卖出10号票
    c号窗口卖出9号票
    b号窗口卖出8号票
    b号窗口卖出7号票
    b号窗口卖出6号票
    b号窗口卖出5号票
    c号窗口卖出4号票
    a号窗口卖出3号票
    a号窗口卖出2号票
    a号窗口卖出1号票
    c号窗口卖出0号票
    b号窗口卖出-1号票

    synchronized放错了位置,程序将synchronized放在了if语句的后面,当b线程取出2好票以后,此时ticket=1,等下一次a、b、c线程来的时候,ticket=1>0就进入if语句体,这时cpu分给线程的时间片是先b在c后a这样就导致了上面的结果。

    例如:

    class thread6Test implements Runnable{
    private int ticket=10;
    public void run()
    {
        synchronized(this){
        for(int i=1;i<50;i++)
        {
            if(ticket>0)
            {
                
                //休眠1s秒中,为了使效果更明显,否则可能出不了效果
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"号窗口卖出"+this.ticket--+"号票");
                }
            }
        }
    }

    输出结果:

    这里的执行结果也是只有a售票。因为同步锁的时候同步了整个的循环。
    整个程序的业务是什么?业务就是售票。换句话说。就是说要售票的时候不能出错。售票的时候各个窗口还有业务彼此不能相互交叉干扰。
    当一个线程要使用火车票这个资源时,我们就交给它一把锁,等它把事情做完后在把锁给另一个要用这个资源的线程

    那么。同步的时候就不是同步程序了。应该是同步销售火车票的这个业务。例如:

    class thread3Test implements Runnable{
        private int ticket=10;
        public void run(){
            for(int i=1;i<50;i++){
                if(ticket>0){
                    try {
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    this.sale();
                }
            }
        }
        public synchronized void sale(){
            if(ticket>0){System.out.println(Thread.currentThread().getName()+"号窗口卖出第"+this.ticket--+"张票!");}
        }
    }

    这里销售火车票就是业务。在这里同步的时候同步业务,而不是同步后台的票的处理的程序。票就算是再处理出来的也是票。
    处理的时候是处理的业务。也就是售票。那么,只要售票的时候不会出现问题就好。同步应该放在业务上,而不是票的处理上。

    我是小菜鸟。这也是我第一次写博客。希望大家能够不吝啬的多多的指教。同时,也感谢各位大师。大神们在博客园的分享。让我学到了很多东西。
    在此,我也把我的一点小小的经验分享出来。希望更多的人能够参与到其中来。
    我也说了。我也是一直小菜鸟。希望大家能够给我多多的指教。我只是写出来了一点我自己的看法还有经验。
    编程这个东西是一个务实,严谨的工作。只有经得起考验的程序才是好的程序。
    在此。也希望大家能够给我多多的指教。提供更多的看法。我也会虚心的采纳。不断的学习。不断的成长。

  • 相关阅读:
    【整理】Dword、LPSTR、LPWSTR、LPCSTR、LPCWSTR、LPTSTR、LPCTSTR
    C/C++中printf和C++中cout的输出格式
    左值的理解(给渴望学习的新手)
    c++ 指针精髓
    c++中的函数前面加个LRESULT是什么意思啊?
    pb调用vc写的动态链接库文件
    C++问题 & *用法
    vs2008下MFC内存泄露问题一点经验
    mysql5.6.41winx64安装
    开发是一件需要非常小心的工作
  • 原文地址:https://www.cnblogs.com/llzzy/p/3026719.html
Copyright © 2020-2023  润新知