• 线程安全问题


    /*
     需求: 模拟3个窗口同时在售50张 票 。
     
    问题1 :为什么50张票被卖出了150次?
    
    出现 的原因: 因为num是非静态的,非静态的成员变量数据是在每个对象中都会维护一份数据的,三个线程对象就会有三份。
    
    解决方案:把num票数共享出来给三个线程对象使用。使用static修饰。
    
    问题2: 出现了线程安全问题 ?
    
    线程 安全问题的解决方案:sun提供了线程同步机制让我们解决这类问题的。
        
        java线程同步机制的方式:
        
            方式一:同步代码块
                
                同步代码块的格式:
                    
                    synchronized(锁对象){
                        需要被同步的代码...
                    }
    
    同步代码块要注意事项:
            1. 任意的一个对象都可以做为锁对象。
            2. 在同步代码块中调用了sleep方法并不是释放锁对象的。
            3. 只有真正存在线程安全问题的时候才使用同步代码块,否则会降低效率的。
            4. 多线程操作的锁 对象必须是 唯一共享的。否则无效。
     synchronized (new Object()) { } 无效
    
    
    synchronized ("锁") { } 有效,
    "锁"被创建后,不会再被创建了。
    5. 一个线程在同步代码块中sleep了,并不会释放锁对象。

               6. 如果不存在着线程安全问题,千万不要使用同步代码块,因为会降低效率。


    出现线程安全问题的根本原因: 1. 存在两个或者两个以上 的线程对象,而且线程之间共享着一个资源。 2. 有多个语句(两句及以上)操作了共享资源。(执行到一半,cpu执行权被抢走)
    */ class SaleTicket extends Thread{ static int num = 50;//票数 非静态的成员变量,非静态的成员变量数据是在每个对象中都会维护一份数据的。 static Object o = new Object(); public SaleTicket(String name) { super(name); } @Override public void run() { while(true){ //同步代码块 synchronized ("锁") { if(num>0){ System.out.println(Thread.currentThread().getName()+"售出了第"+num+"号票"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } num--; }else{ System.out.println("售罄了.."); break; } } } } } public class Demo4 { public static void main(String[] args) { //创建三个线程对象,模拟三个窗口 SaleTicket thread1 = new SaleTicket("窗口1"); SaleTicket thread2 = new SaleTicket("窗口2"); SaleTicket thread3 = new SaleTicket("窗口3"); //开启线程售票 thread1.start(); thread2.start(); thread3.start(); } }

    如果采用第二种方式创建多线程,则不用static修饰num。因为只传了一个对象。

    class SaleTicket implements Runnable{
        
        int  num = 50; // 票数
        
        @Override
        public void run() {
            while(true){
                synchronized ("锁") {
                    if(num>0){
                        System.out.println(Thread.currentThread().getName()+"售出了第"+ num+"号票");
                        num--;
                    }else{
                        System.out.println("售罄了..");
                        break;
                    }    
                }
            }        
        }
    }
    
    public class Demo4 {
        
        public static void main(String[] args) {
            //创建了一个Runnable实现类的对象
            SaleTicket saleTicket = new SaleTicket();
            //创建三个线程对象模拟三个窗口
            Thread thread1 = new Thread(saleTicket,"窗口1");
            Thread thread2 = new Thread(saleTicket,"窗口2");
            Thread thread3 = new Thread(saleTicket,"窗口3");
            //开启线程售票
            thread1.start();
            thread2.start();
            thread3.start();
        }
    }
  • 相关阅读:
    SmartBear正式发布LoadComplete
    CGI, mod_perl, PHP, JSP性能比较
    LoadRunner测试Socket
    性能测试基本功 什么是软件性能
    性能测试基本功 Centos5.5下安装LAMP
    如何聘用优秀的性能测试工程师?
    Spotlight For Oracle使用说明
    SmartBear推出新产品LoadComplete
    LNMP安装
    测试网站性能的在线服务(性能测试云)
  • 原文地址:https://www.cnblogs.com/thiaoqueen/p/6580890.html
Copyright © 2020-2023  润新知