zoukankan      html  css  js  c++  java
  • java 线程(四)线程安全 同步方法

    package cn.sasa.demo2;
    
    import java.util.concurrent.ExecutionException;
    
    public class ThreadDemo {
        public static void main(String[] args) throws InterruptedException, ExecutionException {
            //创建Runnable接口实现类对象
            Ticket t = new Ticket();
            //创建3个Thread类对象,传递Runnable接口实现类
            Thread t0 = new Thread(t);
            Thread t1 = new Thread(t);
            Thread t2 = new Thread(t);
            Thread t3 = new Thread(t);
            
            t0.start();
            t1.start();
            t2.start();
            t3.start();
            /**
              * 线程安全问题一般发生在:
              * 多线程并发访问同一个数据资源
             *  
             *  通过线程休眠,出现了安全问题
             *  
             *   Thread-0 出售第 99
             *   Thread-1 出售第 98
             *   Thread-2 出售第 100
             *   Thread-3 出售第 97
             *   Thread-1 出售第 96
             *   Thread-0 出售第 96
             *   Thread-3 出售第 95
             *   Thread-2 出售第 94
             *   Thread-0 出售第 93
             *   Thread-1 出售第 92
             *   Thread-3 出售第 91
             *   Thread-2 出售第 91
             *   Thread-0 出售第 90
             *   Thread-1 出售第 90
             *   Thread-2 出售第 88
             *   Thread-3 出售第 89
             *   Thread-0 出售第 87
             *   Thread-1 出售第 87 ......
             *   
             *   解决安全问题:
             *   同步代码块
             *   synchronized(任意对象){
             *           线程要操作的共享数据
             *   }
             *   同步代码块中的锁对象可以是任意对象,
             *   但多线程时,要使用同一个锁对象才能够保证线程安全性
             *   
             *   同步方法   在方法声明上加入同步关键字
             *   eg :
             *   private synchronized void func(){
             *       ...
             *   }
             *   同步方法中的对象锁,是本类对象引用 this
             *   如果方法是静态的,锁是本类.class属性
             */
            
            
        }
    }
    package cn.sasa.demo2;
    
    public class Ticket implements Runnable {
        //定义出售的票源
        private int ticket = 100;
        public static int sum = 100; 
        
        public void run(){
            int flag = 100;
          while(flag > 0){
              //buyTickets();
              buy();
              flag --;
          }
        }
        
        //同步方法 synchronized
        private synchronized void buyTickets() {
            if( ticket > 0){
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+" 出售第 "+ticket--);
              }
        }
        
        private static synchronized void buy() {
            if( sum > 0){
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+" 还剩下。。。 "+sum--);
              }
        }
        
    }
  • 相关阅读:
    ApacheCN 所有教程/文档集已备份到 Coding
    固态硬盘寿命天梯榜 2021.7
    一个垃圾佬的自我修养(一)工作站篇
    Java 向上转型
    记一次chromedriver与浏览器版本不匹配导致的问题(mac版本)
    关于C# 里面的axWindowsMediaPlayer的使用
    WCHAR的相关操作 范例 , 同时也是产生创建Sqlserver语句新表的 Sql
    C++ Win32 sokcet2.0版本 TCP 服务器
    C++ WIN 32 socket 2.0版本 TCP客户端
    数据库和传感器糅合 数据部分程序 正常运行
  • 原文地址:https://www.cnblogs.com/SasaL/p/10193949.html
Copyright © 2011-2022 走看看