多线程详解、手撕生产者消费者模型

上面的东西就是很多个进程。每个进程里面包括很多个线程。 线程里又有主线程和分支线程的区别。 就像启动一个java项目。 main函数是主线程,同时会开启一个gc线程垃圾回收。还会开启一些线程。 

像是玩元神, 元神那边有服务器。  我们在玩这个游戏,那么元神的服务器程序会被我占用。    那么,如果别人也想玩元神,也需要占用服务器的程序。 

如果是单线程的, 那么只能我玩几秒钟,别人等我操作结束了,才能进行操作他的角色。    

 如果是都线程就不一样了, 我和别人能够在同一个时刻操控各自的角色,一起愉快的玩原神了。

                                                    

java.Thread

特别喜欢狂神,下面是普通的方法,就是必须要等待 run()方法结束了才能继续往下跑

这里开启了一个子线程,让子线程执行run()方法,主线程继续往下跑

线程船舰的三种方式继承Thread类,Runnable接口,Callable接口。

thread类继承了Runnable接口 都有一个run()方法

Callable接口 有一个call方法

程序需要使用多线程:

那么需要继承thread类,重写run方法 。 函数钟使用它,那么需要调用start方法。

举个列子,为什开启多线程,是同时独立执行的,会产生交替现象(但是线程开启不一定立即执行,是由cpu开启的)

实战:使用多线程下载多个图片

结果可以看到,线程是单独执行的,不是依次向下依次执行的。

实现Runnable接口类 。 将runnable实现的对象放入到thread对象中实现

总结一下继承Thread 和实现Runnable接口 那种方法比较好。一般都是比较建议Runnable的。因为Runnable接口不会是实现的。而Thread是继承的。oop只能够继承一个对象。所以说如果继承了Thread类就不能够继承其他的类了,建议使用Runnabel进行是实现。

那么抢票: 可能会出现问题,数据紊乱

手撕生产者消费者模型

synchronize实现生产者消费者模型


 

package org.example.consumer_and_pro;

public class Message {
    private  int id;
    private  Object message;

    public int getId() {
        return id;
    }

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

    public Object getMessage() {
        return message;
    }
    public Message(int id, Object message) {
        this.id = id;
        this.message = message;
    }

    public void setMessage(Object message) {
        this.message = message;
    }

    @Override
    public String toString() {
        return "Message{" +
                "id=" + id +
                ", message=" + message +
                '}';
    }
}








package org.example.consumer_and_pro;

import java.util.LinkedList;

public class MessageQueue {
    private LinkedList<Message> list = new LinkedList<Message>();
    //初始化容器
    private  int capacity;

    public MessageQueue(int capacity){
        this.capacity = capacity;
    }
      //存入消息
    public  void  put(Message message){
        synchronized (list){
            while (list.size() == capacity){
                try{
                    System.err.println("队列已满,<生产者>请稍后....");
                     list.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            //尾部添加消息
            list.add(message);
            System.out.println("生产消息!"+message);
            //唤醒等待的消费者
            list.notifyAll();


        }


    }
    //获取消息
   public  Message take(){
        synchronized (list){
        while (list.isEmpty()){
            try {
                System.err.println("队列已空,<消费者>请稍后....");
                list.wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        //从对头取出消息并且返回
            Message message = list.removeFirst();
            System.out.println("消费了消息"+message);
        //通知生产者生产
            list.notifyAll();
            return  message;

        }


        }



   }



package org.example.consumer_and_pro;

import java.util.concurrent.TimeUnit;

public class ConAndPro {
    public static void main(String[] args) {
      MessageQueue msque = new MessageQueue(3);
         //生产者
        for (int i = 0; i < 8; i++) {
           //Lambda中引用外部局部变量必须为final
            int id = i;
            new Thread(()->{
                msque.put(new Message(id,"值"+id));
            },"生产者"+i).start();

        }
        new Thread(()->{
            while (true){
                try {
                    TimeUnit.SECONDS.sleep(1);
                    msque.take();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }

        },"消费者").start();




    }






}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玖六儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值