java-等待唤醒机制(线程中的通信)-线程池

Posted 小丑quan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java-等待唤醒机制(线程中的通信)-线程池相关的知识,希望对你有一定的参考价值。

 

 为什么需要线程间的通信

多个线程并发执行时,在默认情况下CPU时随机切换线程的,当我们需要多个线程共同完成一件任务,并且

希望他们有规律的执行,那么多线程之间需要一些协调通信,以此来帮我们达到多线程共同操作一份数据。

如何保证线程间通信有效利用资源

多个线程在处理同一个资源,并且任务不同时,需要线程通信来帮助解决线程之间对同一个遍历的使用或操作

就是多个线程在操作同一份书时,避免对同一个共享变量的争夺,也就是我们需要通过一定的手段使各个线程能有效的利用

资源,这个手段就是等待唤醒机制

 

 

 

机制中用到的方法:

 

 注意:

 

 

 

 

 

调用wait和notify方法需要注意的细节:

 

 

 

 

案例分析:生产者和消费者的问题

 

 

包子类

public class BaoZi {
    public String pi;
    public String xian;
    public   boolean flag =false;
}

 

包子铺线程:‘

public class BaoZiPu extends Thread{
    private BaoZi bz;

    public BaoZiPu(BaoZi bz) {
        this.bz = bz;
    }

    @Override
    public void run() {
        int count =0;

        while (true){
            synchronized (bz){
                if (bz.flag == true){
                    try {
                        bz.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if(count%2 ==0){
                    bz.pi="pi000";
                    bz.xian="xian0000";
                }else {
                    bz.pi="pi111";
                    bz.xian="xian111";
                }
                count++;
                System.out.println("正在做"+bz.xian+bz.pi);
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //做好包子,修改状态
                bz.flag = true;
                //叫醒吃饱人
                bz.notify();
            }
        }

    }
}

 

吃包子线程

public class ChiBaoZI extends Thread{
    private BaoZi bz;

    public ChiBaoZI(BaoZi bz){
        this.bz=bz;
    }

    @Override
    public void run() {
        while (true){
            synchronized (bz){
                if (bz.flag == false){
                    try {
                        bz.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                //唤醒之后
                System.out.println("正在吃包子"+bz.pi+bz.xian);
                //修改包子状态:
                bz.flag = false;
                System.out.println("吃完了");
                System.out.println("+++++++++++++++++");
                bz.notify();//唤醒包子铺做包子

            }
        }
    }



}

 

包子测试:

public class BaoZiTest {
    public static void main(String[] args) {
        BaoZi bz = new BaoZi();
        new BaoZiPu(bz).start();
        new ChiBaoZI(bz).start();
    }
}

 

结果

正在做xian0000pi000
正在吃包子pi000xian0000
吃完了
+++++++++++++++++
正在做xian111pi111
正在吃包子pi111xian111
吃完了
+++++++++++++++++
正在做xian0000pi000
正在吃包子pi000xian0000
吃完了
+++++++++++++++++
正在做xian111pi111
正在吃包子pi111xian111
吃完了
+++++++++++++++++
正在做xian0000pi000
正在吃包子pi000xian0000
吃完了

 

 

线程池

 

 

底层原理

 

 

 

 

 

 

合理利用线程的好处

减低资源消耗,减少创建和销毁线程的次数,每个工作线程都可以被重复里哟ing,可执行多个任务

提高响应速度,当任务到达,可以不要等待线程的创建就能执行

提高线程的客观理性,可以根据系统的可承受能力,调整线程池中工作线程的数目,防止因为消耗过渡的内存,从而把服务器累吧

注意,每个线程需要大约1MB的内存,线程越多,消耗内存也越多

 

 

java中的线程池:

 

 

 

 

建立Runnable 接口的实现类

public class RunnableImpl implements Runnable{

    Lock l = new ReentrantLock();
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());

    }
}

 

建立线程池并使用:

public class DemoThreadPool {
    public static void main(String[] args) {
        ExecutorService es =Executors.newFixedThreadPool(2);
        es.submit(new RunnableImpl());
        es.submit(new RunnableImpl());
        es.submit(new RunnableImpl());
        //线程池会一直开启,使用完线程,会自动回收到线程池,线程可以继续被使用
        //一般不会销毁线程池
    }
}

 

以上是关于java-等待唤醒机制(线程中的通信)-线程池的主要内容,如果未能解决你的问题,请参考以下文章

等待唤醒机制,UDP通信和TCP通信

JAVA学习之等待与唤醒案例线程池Lambda表达式

[javaSE] 多线程通信(等待-唤醒机制)

Java多线程 二 线程间通信

线程通信

JAVA-初步认识-第十四章-线程间通信-等待唤醒机制-代码优化