zoukankan      html  css  js  c++  java
  • 线程安全

    StringBuffer和StringBuilder的区别
    StringBuffer 速度慢,但安全,里面都是同步方法
    StringBuilder 速度快,但不安全,里面没有同步方法

    线程安全问题展示

    package com.orcle.demo01;
    
    public class Tickets implements Runnable {
        //共享数据
        private int ticket=100;
        public void run() {
            while(true){
                if(ticket>0){
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()
                        +"售出了第"+ticket--+"张票");
            }
        }
        }
    
    
    }

    运行结果发现:上面程序出现了问题

    l 票出现了重复的票

    错误的票 0、-1

     

    解决方法

    1.同步代码块

    同步代码块: 在代码块声明上 加上synchronized

    synchronized (锁对象) {

    可能会产生线程安全问题的代码

    }

    同步代码块中的锁对象可以是任意的对象;但多个线程时,要使用同一个锁对象才能够保证线程安全。

    package com.orcle.demo01;
    
    public class Tickets2 implements Runnable {
        //共享数据
        private int ticket=100;
        private Object obj=new Object();
        public void run() {
            
            while(true){
                //同步代码块
                synchronized(obj){
                    //可能会发生线程安全问题代码
                    if(ticket>0){
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName()
                                +"售出了第"+ticket--+"张票");
                    }
                }
            }
        }
    }

    2.同步方法

    l 同步方法:在方法声明上加上synchronized

    public synchronized void method(){

        可能会产生线程安全问题的代码

    }

    同步方法中的锁对象是 this

    package com.orcle.demo01;
    
    public class Tickets3 implements Runnable {
        //共享数据
        private int ticket=100;
        public void run() {
            while(true){
                sale();
            }
        }
        //同步方法(内置锁对象this)
        public synchronized void sale(){
            if(ticket>0){
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()
                    +"售出了第"+ticket--+"张票");
            }
        }
    
    
    }

    3.Lock接口

    package com.orcle.demo01;
    
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class Tickets4 implements Runnable {
        //共享数据
        private int ticket=100;
        //lock 接口实现类对象
        private Lock lock=new ReentrantLock();
        public void run() {
            while(true){
                lock.lock();
                if(ticket>0){
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()
                        +"售出了第"+ticket--+"张票");
            }
                lock.unlock();
        }
        }
    
    
    }
  • 相关阅读:
    Android&Handler2
    ACM&数字阶梯求和(大数问题)
    Android&MyThread
    【转】 《基于MFC的OpenGL编程》Part 15 Selection
    【转】 《基于MFC的OpenGL编程》Part 12 Creating and Using Display Lists
    【转】《基于MFC的OpenGL编程》Part 16 Reflection
    【转】 《基于MFC的OpenGL编程》Part 8 Colors
    【转】 《基于MFC的OpenGL编程》Part 14 Quadrics
    开发不同语言版本的C#程序
    基于ADS40的线阵摄影测量及数据处理
  • 原文地址:https://www.cnblogs.com/longmingyeyu/p/12782722.html
Copyright © 2011-2022 走看看