关于线程同步的问题(阻塞队列)

package com.bootdo.wang;

import java.util.Random;
import java.util.concurrent.LinkedBlockingQueue;

/***
 * 线程同步:
 *   1.方法同步
 *   2.代码块同步
 *   3.使用特殊域变量(volatile)实现线程同步
 *     a.volatile关键字为域变量的访问提供了一种免锁机制,
 *     b.使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新,
 *     c.因此每次使用该域就要重新计算,而不是使用寄存器中的值
 *     d.volatile不会提供任何原子操作,它也不能用来修饰final类型的变量
 *
 *   4.使用重入锁实现线程同步
 *     ReentrantLock类是可重入、互斥、实现了Lock接口的锁,
 *     它与使用synchronized方法和快具有相同的基本行为和语义,并且扩展了其能力
 *     ReentrantLock类的常用方法有:
 *
 *         ReentrantLock() : 创建一个ReentrantLock实例
 *         lock() : 获得锁
 *         unlock() : 释放锁
 *
 *
 *   5.使用局部变量实现线程同步
 *     如果使用ThreadLocal管理变量,则每一个使用该变量的线程都获得该变量的副本,
 *     副本之间相互独立,这样每一个线程都可以随意修改自己的变量副本,而不会对其他线程产生影响。
 *
 *     ThreadLocal 类的常用方法
 *     ThreadLocal() : 创建一个线程本地变量
 *     get() : 返回此线程局部变量的当前线程副本中的值
 *     initialValue() : 返回此线程局部变量的当前线程的"初始值"
 *     set(T value) : 将此线程局部变量的当前线程副本中的值设置为value
 *
 *     注:ThreadLocal与同步机制
 *         a.ThreadLocal与同步机制都是为了解决多线程中相同变量的访问冲突问题。
 *         b.前者采用以"空间换时间"的方法,后者采用以"时间换空间"的方式
 *
 *   6.使用阻塞队列实现线程同步
 *
 *    LinkedBlockingQueue 类常用方法
 *     LinkedBlockingQueue() : 创建一个容量为Integer.MAX_VALUE的LinkedBlockingQueue
 *     put(E e) : 在队尾添加一个元素,如果队列满则阻塞
 *     size() : 返回队列中的元素个数
 *     take() : 移除并返回队头元素,如果队列空则阻塞
 *
 *     注:BlockingQueue<E>定义了阻塞队列的常用方法,尤其是三种添加元素的方法,我们要多加注意,当队列满时:
 *
 *   add()方法会抛出异常
 *
 *   offer()方法返回false
 *
 *   put()方法会阻塞
 *
 *  7.使用原子变量实现线程同步
 *     在java的util.concurrent.atomic包中提供了创建了原子类型变量的工具类,使用该类可以简化线程同步。
 *
 *     其中AtomicInteger 表可以用原子方式更新int的值,可用在应用程序中(如以原子方式增加的计数器),
 *     但不能用于替换Integer;可扩展Number,允许那些处理机遇数字类的工具和实用工具进行统一访问。
 *
 *     AtomicInteger类常用方法:
 *     AtomicInteger(int initialValue) : 创建具有给定初始值的新的AtomicInteger
 *     addAddGet(int dalta) : 以原子方式将给定值与当前值相加
 *     get() : 获取当前值
 *
 *
 *
 */


public class BlockingSynchronizedThread {

    /**
     * LinkBlockinQueue:
     * put(E e)方法:在队尾添加一个元素,如果队列满则阻塞;
     * size():获取队列中的元素的个数
     * take():移除并返回队头元素,如果队列空则阻塞
     */


    private LinkedBlockingQueue<Integer> blockingQueue = new LinkedBlockingQueue<>();

    private final static int size = 10;


    /**
     * 定义标志:0-启动生产线程;1-启动消费进程
     */
    private int flag = 0;


    private class BlockLinkQueueThread implements Runnable {


        @Override
        public void run() {

            int newFlag = flag++;
            System.out.println("启动线程:" + newFlag);

            if (newFlag == 0) {
                // 启动生产进程
                for (int i = 0; i < size; i++) {

                    int b = new Random().nextInt(10);

                    try {
                        blockingQueue.put(b);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    System.out.println("仓库还有" + blockingQueue.size() + "个商品!");

                    try {
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }

            } else {
                // 启动消费线程

                for (int j = 0; j < size / 2; j++) {

                    try {
                        int n = blockingQueue.take();
                        System.out.println("本次消费了" + n + "号商品!");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("仓库中还有" + blockingQueue.size() + "个商品!");

                    try {
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }
            }
        }
    }


    public static void main(String[] args) {

        BlockingSynchronizedThread bst = new BlockingSynchronizedThread();

        BlockLinkQueueThread blqt = bst.new BlockLinkQueueThread();

        Thread thread1 = new Thread(blqt);

        Thread thread2 = new Thread(blqt);


        thread1.start();

        thread2.start();


    }


}

输出:

启动线程:0
启动线程:1
仓库还有1个商品!
本次消费了9号商品!
仓库中还有0个商品!
仓库还有0个商品!
本次消费了5号商品!
仓库中还有0个商品!
仓库还有1个商品!
本次消费了8号商品!
仓库中还有0个商品!
仓库还有1个商品!
本次消费了8号商品!
仓库中还有0个商品!
仓库还有1个商品!
本次消费了2号商品!
仓库中还有0个商品!
仓库还有1个商品!
仓库还有2个商品!
仓库还有3个商品!
仓库还有4个商品!
仓库还有5个商品!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>