0
点赞
收藏
分享

微信扫一扫

QT 的 QSettings 读写 INI 文件的示例

艾米吖 2024-08-12 阅读 18

多线程&JUC-CSDN博客

生产者消费者问题

 

用wait和notify方法实现容量为1的桌子的情况

public class Eater extends Thread {
    public Eater() {
    }

    public Eater(String name) {
        super(name);
    }


    @Override
    public void run() {
        while (true){
            synchronized (Desk.lock){
                if(Desk.foodNum>0){
                    System.out.println("消费者吃");
                    Desk.foodNum--;
                }
                else {
                    try {
                        Desk.lock.wait();//当前线程等待
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}
public class Cook extends Thread{
    public Cook() {
    }

    public Cook(String name) {
        super(name);
    }


    @Override
    public void run() {
        while (true){
            synchronized (Desk.lock){
                if(Desk.foodNum==0){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("生产者做");
                    Desk.foodNum++;
                    Desk.lock.notifyAll();
                }
                else {

                }
            }
        }
    }
}

public class Desk {
     static Lock lock=new ReentrantLock();
     static int foodNum=0;//桌上没有食物,桌子的容量为1


     public static void main(String[] args) {
          Eater eater = new Eater();
          Cook cook = new Cook();
          eater.start();
          cook.start();
     }
}

用阻塞队列实现容量为10的桌子的情况

package com.example.testThread2;

import com.example.testThread2.Cook;
import com.example.testThread2.Eater;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Desk {
     //用阻塞队列实现容量为10的桌子
     static ArrayBlockingQueue<String> queue=new ArrayBlockingQueue<String>(10);

     public static void main(String[] args) {
          Eater eater = new Eater();
          Cook cook = new Cook();
          eater.start();
          cook.start();
     }
}
package com.example.testThread2;



public class Eater extends Thread {
    public Eater() {
    }

    public Eater(String name) {
        super(name);
    }


    @Override
    public void run() {
        while (true){
                try {
                    Thread.sleep(600);
                    Desk.queue.take();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            System.out.println("消费者吃了一碗面条,现在桌上还有"+Desk.queue.size()+"碗");
        }
    }
}
package com.example.testThread2;



public class Cook extends Thread{
    public Cook() {
    }

    public Cook(String name) {
        super(name);
    }


    @Override
    public void run() {
        while (true){
            try {
                if(Desk.queue.size()>5)
                {
                    Thread.sleep(1000);
                    Desk.queue.put("面条");
                }
                else {
                    Thread.sleep(300);
                    Desk.queue.put("面条");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("生产者做了一碗面条,现在桌上还有"+Desk.queue.size()+"碗");

        }
    }
}


线程的状态

实际上java中定义的线程状态只有其中的6种,不包括上图的运行状态,因为运行时JVM把线程交给操作系统处理了。

线程池

 线程池核心原理

线程池代码实现

public class PoolTask implements Runnable{
    @Override
    public void run() {
//        for (int i = 0; i < 100; i++) {
//            System.out.println(Thread.currentThread().getName()+":"+i);
//        }
        System.out.println(Thread.currentThread().getName());

    }
}
    @Test
    public void test05() throws InterruptedException {
        /*
            线程池
         */
        //1.创建线程池对象
//        ExecutorService threadPool = Executors.newCachedThreadPool();
        ExecutorService threadPool = Executors.newFixedThreadPool(3);//创建一个上限为3的线程池
        //2.提交任务
        threadPool.submit(new PoolTask());

        threadPool.submit(new PoolTask());
//        Thread.sleep(1000);
        threadPool.submit(new PoolTask());
//        Thread.sleep(1000);
        threadPool.submit(new PoolTask());
//        Thread.sleep(1000);
        threadPool.submit(new PoolTask());
        //销毁线程池
        threadPool.shutdown();
    }

上限为3的线程池

无上限的线程池

自定义线程池

相关参数

情况1 :何时创建临时进程

核心线程----->等待队列----->临时线程

情况2:什么情况下触发拒绝策略

答:核心线程、等待队列、临时线程都被占用了。

4种任务拒绝策略

采用第三种策略,将抛弃任务4

自定义线程池初体验

    @Test
    public void test07(){
        //两个核心线程+两个临时线程+长度为2的等待队列
        ThreadPoolExecutor myThreadPool = new ThreadPoolExecutor(
                2,//核心线程数
                4,//最大线程数
                1,//空闲线程最大存活时间
                TimeUnit.MINUTES,//时间单位
                new ArrayBlockingQueue<>(2),//长度为3的等待队列
                Executors.defaultThreadFactory(),//创建线程工厂
                new ThreadPoolExecutor.AbortPolicy()//设置拒绝策略:丢弃任务并抛出异常
        );
        myThreadPool.submit(new PoolTask());
        myThreadPool.submit(new PoolTask());
        myThreadPool.submit(new PoolTask());
        myThreadPool.submit(new PoolTask());
        myThreadPool.submit(new PoolTask());
        myThreadPool.submit(new PoolTask());
        myThreadPool.submit(new PoolTask());//到这里就执行拒绝策略了
        myThreadPool.submit(new PoolTask());
        myThreadPool.submit(new PoolTask());
        myThreadPool.submit(new PoolTask());
        myThreadPool.shutdown();

    }

 

怎样设计线程池?

最大并行数=8*2=16

对于CPU密集型计算,以我电脑的配置,线程池的最大线程数可设为:16+1=17

举报

相关推荐

0 条评论