线程安全

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();
    }
    }


}

 

posted @ 2020-04-26 22:12  龙茗夜雨  阅读(123)  评论(0编辑  收藏  举报