Java线程安全-同步方式

/**
 * Java经典的同步案例:生产者-消费者问题
 * 生产者不断地往货架上放产品,消费者不断地从货架上取产品
 * 货架容量有限,货架满时不能放产品,货架空时不能取产品
 * 这是一个简单的同步问题,当线程A访问临界资源时,其他线程不
 * 必一直等待,可以先回家休息,当线程A访问结束时再通知其他线
 * 程可以访问临界资源了。
 * 
 * @author 景向后山
 */

/*
 * 自定义Stack类
 */
class Stack {
    private Object[] data;
    private int top;
    private int size = 50;

    public Stack() {
        this.data = new Object[this.size];
        top = 0;
    }

    public Stack(int size) {// 指定初始大小的构造方法
        this.size = size;
        this.data = new Object[this.size];
        top = 0;
    }

    public boolean empty() {// 判断栈是否为空
        return top > 0 ? false : true;
    }

    public boolean full() {// 判断栈是否已满
        return top < size ? false : true;
    }

    public boolean push(T e) {// 元素入栈
        if (full()) {
            return false;
        } else {
            this.data[top++] = e;
            return true;
        }
    }

    public T pop() {// 弹出栈顶元素
        if (top == 0) {
            return null;
        } else {
            T e = (T) data[top - 1];
            data[--top] = null;
            return e;
        }
    }

    public T getTop() {// 获得栈顶元素,但不弹栈
        if (top == 0) {
            return null;
        } else {
            T e = (T) data[top - 1];
            return e;
        }
    }
}

/*
 * 消费者
 */
class Consumer implements Runnable {

    private Storage storage;

    public Consumer(Storage storage) {
        super();
        this.storage = storage;
    }

    @Override
    public void run() {
        for (int i = 0; i < 6; i++) {
            storage.pop();// 消费者消费产品
        }
    }

}

/*
 * 生产者
 */
class Producer implements Runnable {
    private Storage storage;

    public Producer(Storage storage) {
        super();
        this.storage = storage;
    }

    @Override
    public void run() {
        for (int i = 0; i < 6; i++) {
            // 生产者生产产品
            Product product = new Product(String.valueOf(100 + i));
            storage.push(product);// 产品入栈
        }
    }

}
/*
 * 产品类
 */

class Product {
    private String id;

    public Product(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

}

/*
 * 货架栈实现类
 */
class Storage {
    Stack stack = new Stack<>(3);// 定义货架的初始大小

    public synchronized void push(Product product) {
        while (stack.full()) {// 判断货架是否已满
            try {
                System.out.println("货架已满,请等待!");
                wait();
            } catch (Exception e) {
            }
        }
        stack.push(product);// 生产者生产产品入货架栈
        String producer = Thread.currentThread().getName();
        System.out.println(producer + "生产了" + product.getId() + "号产品!");
        notifyAll();// 唤醒所有因为访问synchronized方法而休眠的方法
    }

    public synchronized Product pop() {
        while (stack.empty()) {// 判断货架是否为空
            try {
                System.out.println("货架已空,请等待!");
                wait();
            } catch (Exception e) {
            }
        }
        Product product = stack.pop();// 消费者消费产品,货架产品弹栈
        String producer = Thread.currentThread().getName();
        System.out.println(producer + "消费了" + product.getId() + "号产品!");
        notifyAll();// 唤醒所有因为访问synchronized方法而休眠的方法
        return product;
    }
}

/*
 * 生产者消费者问题主方法
 */

public class MyThreadTest {
    public static void main(String[] args) {
        // 生产者和消费者共享一个货架
        Storage storage = new Storage();
        Thread consumer = new Thread(new Consumer(storage), "消费者");
        Thread producer = new Thread(new Producer(storage), "生产者");
        consumer.start();
        producer.start();
    }
}

你可能感兴趣的:(Java笔记)