美文网首页
线程相关(二)同步线程

线程相关(二)同步线程

作者: 云鲸鱼rain | 来源:发表于2019-03-06 10:25 被阅读0次
    图片来源:https://blog.csdn.net/luoweifu/article/details/46673975

    上代码(先上的是错误代码,先找错误原因,再上正确代码)

    package test;
    
    public class ThreadSyn implements Runnable{
        
        private Integer sum;//票总数
        
        private Integer current = 1;//当前出售票(初始值为1)
        
        public ThreadSyn(Integer sum) {
            this.sum = sum;
        }
    
        @Override
        public void run() {
            while(sum-current >= 0) {
                System.out.print(Thread.currentThread().getName() + "出售第" + current + "张票。");
                if(current <= sum) {
                    System.out.println("售票成功!还剩" + (sum-current) + "张票。");
                        current++;
                } else {
                    System.out.println("售票失败!该票已售完。");
                }
            }
        }
    }
    
    
    package test;
    
    public class ThreadTest {
        
         public static void main(String args[]) {        
             ThreadSyn threadSyn = new ThreadSyn(5);
             Thread threads[] = new Thread[3];
             for(int i=0;i<threads.length;i++) {
                 threads[i] = new Thread(threadSyn, "第" + (i+1) + "个窗口");
                 threads[i].start();
             } 
         }
    }
    

    错误代码在运行之前,看着逻辑是没问题了。运行结果:

    第3个窗口出售第1张票。第1个窗口出售第1张票。售票成功!还剩4张票。
    第2个窗口出售第1张票。第1个窗口出售第2张票。售票成功!还剩4张票。
    售票成功!还剩3张票。
    售票成功!还剩3张票。
    第1个窗口出售第4张票。第3个窗口出售第3张票。售票成功!还剩0张票。
    第2个窗口出售第5张票。售票成功!还剩0张票。
    售票失败!该票已售完。
    

    显然不对。原因就是多个线程同时进了run方法。那就限制成单个线程。

    再上代码:(正确代码)

    package test;
    
    public class ThreadSyn implements Runnable{
        
        private Integer sum;//票总数
        
        private Integer current = 1;//当前出售票(初始值为1)
        
        public ThreadSyn(Integer sum) {
            this.sum = sum;
        }
    
        @Override
        public void run() {
            while(sum-current >= 0) {
                synchronized (this) {
                    System.out.print(Thread.currentThread().getName() + "出售第" + current + "张票。");
                    if(current <= sum) {
                        System.out.println("售票成功!还剩" + (sum-current) + "张票。");
                        try {
                            Thread.sleep(100);
                            current++;
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    } else {
                        System.out.println("售票失败!该票已售完。");
                    }
                }
            }
        }
    }
    
    package test;
    
    public class ThreadTest {
        
         public static void main(String args[]) {        
             ThreadSyn threadSyn = new ThreadSyn(500);
             Thread threads[] = new Thread[8];
             for(int i=0;i<threads.length;i++) {
                 threads[i] = new Thread(threadSyn, "第" + (i+1) + "个窗口");
                 threads[i].start();
             } 
         }
    }
    

    输出结果:(内容太多,中间就用......代替了)

    第1个窗口出售第1张票。售票成功!还剩499张票。
    第1个窗口出售第2张票。售票成功!还剩498张票。
    第1个窗口出售第3张票。售票成功!还剩497张票。
    第8个窗口出售第4张票。售票成功!还剩496张票。
    第8个窗口出售第5张票。售票成功!还剩495张票。
    ......
    第3个窗口出售第495张票。售票成功!还剩5张票。
    第3个窗口出售第496张票。售票成功!还剩4张票。
    第3个窗口出售第497张票。售票成功!还剩3张票。
    第4个窗口出售第498张票。售票成功!还剩2张票。
    第4个窗口出售第499张票。售票成功!还剩1张票。
    第4个窗口出售第500张票。售票成功!还剩0张票。
    第5个窗口出售第501张票。售票失败!该票已售完。
    第6个窗口出售第501张票。售票失败!该票已售完。
    第7个窗口出售第501张票。售票失败!该票已售完。
    第8个窗口出售第501张票。售票失败!该票已售完。
    第1个窗口出售第501张票。售票失败!该票已售完。
    第3个窗口出售第501张票。售票失败!该票已售完。
    第2个窗口出售第501张票。售票失败!该票已售完。
    

    正确代码比错误代码多了两个内容。
    一个是 synchronized (this) {} 同步锁,是解决错误代码问题的地方。
    一个是 Thread.sleep(100); 这个就是使当前线程暂时0.1秒,这样肉眼才能看到刷刷刷的在售票,不然刷一下500张票全出来了。只是为了方便观察。

    相关文章

      网友评论

          本文标题:线程相关(二)同步线程

          本文链接:https://www.haomeiwen.com/subject/vrnzuqtx.html