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();
        }
        }
    
    
    }
  • 相关阅读:
    java List按照对象的属性进行分组
    postgresql数据库大量锁表的问题解决
    postgresql 并发update下导致的死锁问题
    Spring Boot 2.X(十):自定义注册 Servlet、Filter、Listener
    Spring Cloud(一):入门篇
    Spring Boot 2.X(九):Spring MVC
    Spring Boot 2.X(八):Spring AOP 实现简单的日志切面
    Spring Boot 2.X(七):Spring Cache 使用
    Spring Boot 2.X(六):Spring Boot 集成 Redis
    Spring Boot 2.X(五):MyBatis 多数据源配置
  • 原文地址:https://www.cnblogs.com/longmingyeyu/p/12782722.html
Copyright © 2011-2022 走看看