多线程——生产者和消费者问题

缓冲区:

//缓冲区:拥有一个值,可以设置可以获得
public class Buffer {

    int value;

    public int getValue() {  //消费者,得到值
        System.out.println("    取得值" + value);
        return value;
    }

    public void setValue(int value) {   //生产者:设置值
        this.value = value;
        System.out.println("设置值" + value);
    }


}

生产者线程:

//生产者线程
public class SetThread extends Thread{

    Buffer buffer;//缓冲区

    public SetThread(Buffer buffer) {
        super();
        this.buffer = buffer;
    }

    public void run() {

        for(int i = 0; i < 30; i++){
            buffer.setValue(i);
        }
    }

}

消费者线程:

//消费者线程
public class GetThread extends Thread{

    Buffer buffer;//缓冲区

    public GetThread(Buffer buffer) {
        super();
        this.buffer = buffer;
    }

    public void run() {

        for(int i = 0; i < 30; i++){
            buffer.getValue();
        }
    }

}

测试:


public class BufferTest {

    public static void main(String[] args) {
        Buffer buf = new Buffer();

        SetThread setThread = new SetThread(buf);
        GetThread getThread = new GetThread(buf);

        setThread.start();
        getThread.start();

    }

}

输出:

设置值0
设置值1
设置值2
    取得值0
    取得值3
    取得值3
    取得值3
    取得值3
    取得值3
    取得值3
    取得值3
    取得值3
    取得值3
    取得值3
    取得值3
    取得值3
    取得值3
    取得值3
设置值3
设置值4
设置值5
设置值6
    取得值3
设置值7
设置值8
设置值9
    取得值7
设置值10
设置值11
设置值12
    取得值10
设置值13
设置值14
设置值15
    取得值13
设置值16
    取得值16
设置值17
设置值18
    取得值18
设置值19
    取得值19
设置值20
    取得值20
设置值21
设置值22
设置值23
    取得值21
设置值24
    取得值24
设置值25
设置值26
设置值27
设置值28
    取得值25
    取得值29
    取得值29
    取得值29
设置值29
    取得值29

继续完善:synchronized线程同步 使得资源有序竞争

//缓冲区:拥有一个值,可以设置可以获得
public class Buffer {

    int value;
    boolean flag =false;//通信的标志。有没有值可取的标志


    public synchronized int getValue() {  //加上一把锁
        if(!flag){//没有值
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

        System.out.println("       取得值" + value);
        flag = false;
        notify();//将等待这个资源的其他进程唤醒
        return value;
    }

    public synchronized void setValue(int value) {  //生产者:设置值
        if(flag){//有数值可取
            try {
                wait();//Object类的一个方法
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        //flag为false:没有数值可取,所以要进行设置
            this.value = value;
            System.out.println("设置值" + value);  
            flag = true;
            notify();//唤醒消费者线程
    }

}

生产者和消费者线程不变
输出为:资源有序

设置值0
       取得值0
设置值1
       取得值1
设置值2
       取得值2
设置值3
       取得值3
设置值4
       取得值4
设置值5
       取得值5
设置值6
       取得值6
设置值7
       取得值7
设置值8
       取得值8
设置值9
       取得值9
设置值10
       取得值10
设置值11
       取得值11
设置值12
       取得值12
设置值13
       取得值13
设置值14
       取得值14
设置值15
       取得值15
设置值16
       取得值16
设置值17
       取得值17
设置值18
       取得值18
设置值19
       取得值19
设置值20
       取得值20
设置值21
       取得值21
设置值22
       取得值22
设置值23
       取得值23
设置值24
       取得值24
设置值25
       取得值25
设置值26
       取得值26
设置值27
       取得值27
设置值28
       取得值28
设置值29
       取得值29

猜你喜欢

转载自blog.csdn.net/gx17864373822/article/details/80177809