java之线程安全

出现线程不安全的三个条件
  1. 是多线程环境
  2. 线程之间有共享数据
  3. 对共享数据的操作是多句
    处理线程安全方法:同步块/同步方法
    多线程之生产者、消费者模式
    生产者:
public class Producer implements Runnable {
    private Milk milk;

    public Producer(Milk milk){
        this.milk = milk;
    }
    public void run() {

            for (int i=1;i<10;i++){
                try {
                    milk.put(i);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    }
}

消费者:


public class Consumer implements Runnable {
    private Milk milk;

    public Consumer(Milk milk){
        this.milk = milk;
    }
    public void run() {

            while (true){
                try{
                    milk.get();
                }catch (Exception e){
                    e.printStackTrace();
                }

            }
    }
}

缓冲区:


public class Milk {
    private int milk;
    private boolean state=false;//有奶:true;无奶:false

    public synchronized  void put(int i) throws InterruptedException {
        if (state){
            wait();
        }
        this.milk = i;
        System.out.println("送奶工送入第"+i+"瓶奶");
        state = true;
        notifyAll();
    }

    public synchronized  void  get() throws InterruptedException {
        if (!state){
           wait();
        }
        System.out.println("消费者喝了第"+milk+"瓶奶");
        state = false;
        notifyAll();
    }
}

Milk 中属性:milk 是Producer和Consumer线程共用的数据,并且对共用的数据操作是非原子性的。因此对这样的资源的操作要加锁。所以在Milk中对milk的各种操作方法要加锁。
方法二:Lock锁

public class Ticket implements Runnable {
    private int ticket = 100;
    private Lock lock = new ReentrantLock();
    public void run() {

        while (true){
            lock.lock();
            if (ticket>0){
                System.out.println(Thread.currentThread().getName()+"完成买票,余票为"+--ticket);
            }
            lock.unlock();
        }


    }
}

测试类:


public class TicketTest {
    public static void main(String[] args) {
        Runnable ticket = new Ticket();

        Thread thread1 = new Thread(ticket,"窗口一");
        Thread thread2 = new Thread(ticket,"窗口二");
        Thread thread3 = new Thread(ticket,"窗口三");

        thread1.start();
        thread2.start();
        thread3.start();
    }
}

三个线程共享Ticket中的ticket变量,Ticket中对ticket的操作不是原子性的因此需要加锁。
线程安全类:
StringBuffer、vector、HashTable 是线程安全类。一般不使用Vector,使用Collections类的静态方法直接将线程不全的集合转为线程安全的集合。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值