多线程同步

关于线程同步问题,最经典的案例就是“生产者与消费者的同步问题"了,消费者和生产者之间可以有一个缓冲区,为什么要有这个缓冲区呢?
缓冲区就相当于我们平时逛的商场,便利店之类的地方,充当一个中间人的角色,生产者生产出来的产品可以直接丢给中间人,不用去等待消费者去消费,一定程度上实现了程序之间的解耦,和防止线程阻塞带来的效率问题。
这里简要说一下他们之间的关系:
①生产者在没有产品的时候开始生成,消费者等待
②消费者在产品满的时候开始消费,生产者等待
消费者在没有产品的时候会通知生产者生产
生产者在产品满的时候通知消费者进行消费
实现生产者与消费者模型,有三种方式:
一 使用synchronized关键字,传递参数产品,表示在生产或消费的时候,另一方不能进行操作
wait()、notifiyall()方法是实现线程间的通信
二 在生产和消费方法上加上synchronized关键字,变成同步方法,同步对象是产品类本身,
也是使用wait()、notifyAll()方法实现线程间的通信,需要注意的是wait()和 notifyall()的条件
三 使用lock、condition 实现
await()方法和signalall()方法实现线程间的通讯,同样要注意方法的条件

方式1:

package produceComsumer;

import java.util.ArrayList;

/**
 * Created on 10:59  02/09/2019
 * Description:
 *
 * @author Weleness
 */

public class Producer {
    public  Object obj;
    public ArrayList<Integer> list;//用list存放生产之后的数据,最大容量为1

    public Producer(Object obj, ArrayList<Integer> list) {
        this.obj = obj;
        this.list = list;
    }

    public void prodece(){
        synchronized (obj){
            while (!list.isEmpty()){
                System.out.println("生产者"+Thread.currentThread().getName()+"waiting");
                try {
                    obj.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            int value = 9999;
            list.add(value);
            System.out.println("生产者"+Thread.currentThread().getName()+"Runnable");
            obj.notifyAll();
        }
    }
}

package produceComsumer;

import java.util.ArrayList;

/**
 * Created on 11:15  02/09/2019
 * Description:
 *
 * @author Weleness
 */

public class Comsumer {
    private Object obj;
    private ArrayList<Integer> list;

    public Comsumer(Object obj, ArrayList<Integer> list) {
        this.obj = obj;
        this.list = list;
    }

    public void comsuemr(){
        synchronized (obj){
            while (list.isEmpty()){
                System.out.println("消费者"+Thread.currentThread().getName()+"waiting");
                try {
                    obj.wait();//手动释放obj锁
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            list.clear();
            System.out.println("消费者"+Thread.currentThread().getName()+"Runnable");
            obj.notifyAll();//唤醒所有在这个锁上阻塞的线程
        }
    }
}

方式2:

package produceComsumer;

import java.util.ArrayList;
import java.util.Collections;
/**
 * Created on 11:36  02/09/2019
 * Description:
 *
 * @author Weleness
 */

public class MyService {
    private ArrayList<Integer> list;

    public MyService(ArrayList<Integer> list) {
        this.list = list;
        Collections.synchronizedList(list);
    }

    synchronized void produce() {

       while (list.size()!=0) {
            try {
                System.out.println(Thread.currentThread().getName() + "waiting");
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
           int value = 9999;
           list.add(value);
            System.out.println(Thread.currentThread().getName()+"Runnable");
            notifyAll();
        }
    }

     synchronized void comsumer() {
        while (list.size()==0){
            try {
                System.out.println(Thread.currentThread().getName()+"waiting");
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        list.clear();
        System.out.println(Thread.currentThread().getName()+"Runnable");
        this.notifyAll();
    }
}

package produceComsumer;

/**
 * Created on 11:43  02/09/2019
 * Description:
 *
 * @author Weleness
 */

public class ComsumerThraed2 extends Thread {
     private MyService ms;

    public ComsumerThraed2(MyService ms) {
        this.ms = ms;
    }

    public void run(){
        while (true){
            ms.comsumer();
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

package produceComsumer;

/**
 * Created on 11:36  02/09/2019
 * Description:
 *
 * @author Weleness
 */

public class ProduceThread2  extends Thread{
    private MyService ms ;

    public ProduceThread2(MyService ms) {
        this.ms = ms;
    }

    public void run(){
        while (true){
           ms.produce();
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

方式3:

package produceComsumer;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created on 15:48  02/09/2019
 * Description:
 *
 * @author Weleness
 */

public class MyServiceLcok {
    private ReentrantLock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    private  boolean hasValue = false;

    public  void  produce(){
        lock.lock();
        try {
        while (hasValue==true){
            System.out.println(Thread.currentThread().getName()+"waiting");

                condition.await();
            }
            hasValue = true;
            System.out.println(Thread.currentThread().getName()+"Runnable");
            condition.signalAll();
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
    public void comsumer(){
        lock.lock();
        try {
            while (hasValue==false){
                System.out.println(Thread.currentThread().getName()+"waiting");
                condition.await();
            }
           hasValue=false;
            System.out.println(Thread.currentThread().getName()+"Runnable");
            condition.signalAll();
        }catch (InterruptedException e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }

    }
}

package produceComsumer;

/**
 * Created on 15:54  02/09/2019
 * Description:
 *
 * @author Weleness
 */

public class ProduceThreadLock extends Thread {
    private MyServiceLcok p;

    public ProduceThreadLock(MyServiceLcok p) {
        this.p = p;
    }

    @Override
    public void run() {
        while (true){
            p.produce();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

package produceComsumer;

/**
 * Created on 15:55  02/09/2019
 * Description:
 *
 * @author Weleness
 */

public class ComsumerThreadLock extends Thread {
    private MyServiceLcok c ;

    public ComsumerThreadLock(MyServiceLcok c) {
        this.c = c;
    }

    @Override
    public void run() {
        while (true){
            c.comsumer();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

参考文章
https://blog.csdn.net/u011109589/article/details/80519863

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值