java学习日记 -线程的协作及线程池的学习

2021/8/17 22:06:12

本文主要是介绍java学习日记 -线程的协作及线程池的学习,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

嗯嗯..对于一个新手来说,线程的协同作用翻译过来就是就是多个线程要处理同一个资源,处理的动作有先后或者制约的束缚。比如A线程生成包子,B线程吃包子,只有A生成包子B才能吃到,再多一点约束比如只有B吃了包子A才会做新的包子,这样线程A和线程B就有了协同的作用。

刚刚的包子生产其实就是生产者与消费者问题,之前在学校学习操作系统中已经有过比较深入的了解(PV信号量),这就要使用到线程的等待唤醒机制(wait-notify)

这是包子问题的简单实现:

public class PVTest {
    public static void main(String[] args) {
        Baozi baozi = new Baozi();
        Chihuo c = new Chihuo("胡建",baozi);
        Baozipu b = new Baozipu("狗不理包子铺",baozi);
        c.start();
        b.start();
    }
}


class Baozi{                              //资源类
    String pier;
    String xianer;
    boolean flag = false;
}


class Chihuo extends Thread{            //通过继承Thread来创建线程
    private Baozi baozi;
    public Chihuo(String name,Baozi baozi){
        super(name);
        this.baozi = baozi;
    }

    @Override
    public void run() {
        while(true){
            synchronized (baozi){       //同步线程,重要的是协同的两个线程锁一定是一样的
              if(baozi.flag == false){
                  try{
                      baozi.wait();     //要是没有包子了吃货就等着呗
                  }catch (InterruptedException e){
                      e.printStackTrace();
                  }
              }
              System.out.println("吃货正在吃"+baozi.pier+baozi.xianer+"包子");
              baozi.flag = false;
              baozi.notify();          //唤醒线程
                try {
                    Thread.sleep(400);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    }
}}


class Baozipu extends Thread{
    private Baozi baozi;
    public Baozipu(String name,Baozi baozi){
        super(name);
        this.baozi = baozi;
    }
    int count = 0;

    @Override
    public void run() {
        while(true){
            synchronized (baozi){
                if(baozi.flag == true){          //要是有包子就等吃货吃完再做
                    try{
                        baozi.wait();
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                }
                if(count%2==0){                 //这里就是随便弄两种包子
                    baozi.pier = "冰皮";
                    baozi.xianer = "素三鲜";
                }
                else{
                    baozi.pier = "薄皮";
                    baozi.xianer = "猪肉大葱";
                }
                count++;
                System.out.println("包子铺做好了"+baozi.pier+baozi.xianer+"饺子");
                System.out.println("可以吃了啊");
                baozi.flag = true;
                baozi.notify();
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

通过这种实例就比较容易理解线程协同工作,但是值得注意的是唤醒的线程不一定立刻就可以运行,如果没有获得锁唤醒的线程就会进入就绪状态

接下来我还学习到了线程池的概念

线程池: 其实就是一个容纳多个线程的容器 ,其中的线程可以反复使用 ,省去了频繁创建线程对象的操作 , 无需反复创建线程而消耗过多资源。 合理利用线程池能够带来三个好处: 1. 降低资源消耗。减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。 2. 提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。 3. 提高线程的可管理性。可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内 存,而把服务器累趴下 ( 每个线程需要大约 1MB 内存 ,线程开的越多,消耗的内存也就越大,最后死机 ) 。 那我们该怎样创建线程池呢? Java 里面线程池的顶级接口是 java.util.concurrent.Executor ,但是严格意义上讲 Executor 并不是一个线程 池,而只是一个执行线程的工具。真正的线程池接口是 java.util.concurrent.ExecutorService 。 要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚的情况下,很有可能配置的线程池不是较优 的,因此在 java.util.concurrent.Executors 线程工厂类里面提供了一些静态工厂,生成一些常用的线程池。官 方建议使用 Executors 工程类来创建线程池对象。 Executors 类中有个创建线程池的方法如下: public static ExecutorService newFixedThreadPool(int nThreads) :返回线程池对象。 ( 创建的是有界线 程池 , 也就是池中的线程个数可以指定最大数量 ) 获取到了一个线程池 ExecutorService 对象,那么怎么使用呢,在这里定义了一个使用线程池对象的方法如下: public Future<?> submit(Runnable task) : 获取线程池中的某一个线程对象,并执行 Future 接口:用来记录线程任务执行完毕后产生的结果。线程池创建与使用。 使用线程池中线程对象的步骤: 1. 创建线程池对象。 2. 创建 Runnable 接口子类对象。 (task) 3. 提交 Runnable 接口子类对象。 (take task) 4. 关闭线程池 ( 一般不做 ) 。 以上是我从教科书COPY下来,作为初学者我还没能够弄懂其中的种种机制,只是学会了创建线程池并且使用其中线程

这篇关于java学习日记 -线程的协作及线程池的学习的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程