• 进程和线程2


    1. package com.yan4;
    2. public class Test21 {
    3. public static void main(String[] args) {
    4. MyRunnable21[] arr=new MyRunnable21[10];
    5. for(int i=1;i<=10;i++) {
    6. MyRunnable21 r=new MyRunnable21((i-1)*100+1, i*100);
    7. arr[i-1]=r;
    8. new Thread(r).start();
    9. }
    10. try {
    11. Thread.sleep(5000);
    12. } catch (InterruptedException e) {
    13. e.printStackTrace();
    14. }
    15. for(int i=0;i
    16. System.out.println(arr[i].getRes());
    17. }
    18. }
    19. }
    20. class MyRunnable21 implements Runnable{
    21. private int begin,end,res=0;
    22. public MyRunnable21(int begin,int end) {
    23. this.begin=begin;
    24. this.end=end;
    25. }
    26. @Override
    27. public void run() {
    28. for(int k=begin;k<=end;k++) {
    29. res+=k;
    30. }
    31. }
    32. public int getRes() {
    33. return res;
    34. }
    35. }
    1. package com.yan4;
    2. public class Test22 {
    3. static int result=0;
    4. public static void main(String[] args) throws InterruptedException {
    5. for(int i=1;i<=10;i++) {
    6. int begin=(i-1)*100+1;
    7. int end=i*100;
    8. new Thread(new Runnable() {
    9. int res=0;
    10. @Override
    11. public void run() {
    12. for(int k=begin;k<=end;k++)
    13. res+=k;
    14. result+=res;
    15. }
    16. }).start();
    17. }
    18. Thread.sleep(2000);
    19. System.out.println(result);
    20. }
    21. }

    使用Callable接口和Future接口创建线程代码如下:

    java.util.concurrent.Callable  有时候java.util.concurrent包可以称为juc包@FunctionalInterface  注解用于声明当前接口是一个函数式接口
    public interface Callable {  这里<>中用于声明返回值的类型
       V call() throws Exception;  真正执行的方法,有返回值,允许抛出异常

    }

     

    线程的构造器为
    public Thread(Runnable target) {
          this(null, target, "Thread-" + nextThreadNum(), 0);
      }
      
      Future接口
      public interface Future {
      boolean cancel(boolean mayInterruptIfRunning);  可以取消正在运行的线程
      boolean isCancelled(); 判断是否取消
      boolean isDone(); 判断线程是否在运行中
      V get() throws InterruptedException, ExecutionException; 获取线程执行的结果
      V get(long timeout, TimeUnit unit)throws InterruptedException, ExecutionException, TimeoutException;

        Java针对Future接口提供的具体实现类FutureTask
        
        源代码:
        public class FutureTask implements RunnableFuture
        
        public interface RunnableFuture extends Runnable, Future
        
        构造器
          public FutureTask(Callable callable) {
          if (callable == null)
              throw new NullPointerException();
          this.callable = callable;
          this.state = NEW;       // ensure visibility of callable
      }
        
        public void run() {
              Callable c = callable;
              ...
                      result = c.call();
      }

    1. public class Test3 {
    2. public static void main(String[] args) throws Exception {
    3. //为了获取返回值,所以需要使用FutureTask中提供的get方法
    4. FutureTask[] arr=new FutureTask[10];
    5. for(int i=1;i<=10;i++) {
    6. int begin=(i-1)*100+1;
    7. int end=i*100;
    8. //定义Callable的实现
    9. Callable c=new Callable() {
    10. public Integer call() throws Exception {
    11. int res=0;
    12. for(int k=begin;k<=end;k++)
    13. res+=k;
    14. return res;
    15. }
    16. };
    17. // Runnable r=new FutureTask<>(c);
    18. //构建FutureTask对象,其中包含Callable对象
    19. FutureTask ft=new FutureTask<>(c);
    20. //不是必须的,只是证明FutureTask实现类Runnable接口
    21. Runnable r=ft;
    22. arr[i-1]=ft;
    23. //启动线程,构建Thread对象时,要求参数类型为Runnable接口类型
    24. //线程执行时会自动调用run方法,而FutureTask中提供的run方法会调用Callable对象的call方法
    25. new Thread(r).start();
    26. }
    27. int res=0;
    28. for(FutureTask tmp:arr)
    29. res+=tmp.get();//main线程执行到这里时,会自动阻塞等待子线程tmp执行结束,执行结束后获取call方法的返回值
    30. System.out.println(res);
    31. }
    32. }

    注意:FutureTask实现了Future和Runnable接口,所以new Thread(futureTask),当执行thread.start()方法时会自动调用Callable接口实现中的call方法。当调用futureTask.get()方法时可以获取对应的线程对象的执行结果,如果线程并没有返回时,当前线程阻塞等待

    使用线程池创建线程

    享元模式

    享元模式Flyweight Pattern主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式

    •  优点:大大减少对象的创建,降低系统内存的使用,以提高程序的执行效率。
    • 缺点:提高了系统的复杂度,需要分离出外部状态和内部状态,而且外部状态具有固有化的性质,不应该随着内部状态的变化而变化,否则会造成系统的混乱。
    1. public class Test4 {
    2. public static void main(String[] args) {
    3. for(int i=0;i<10;i++) {
    4. IShape tmp=ObjectManager.getInstance();
    5. System.out.println(tmp);
    6. ObjectManager.relessInstance(tmp);
    7. }
    8. }
    9. }
    10. interface IShape{
    11. public void draw();
    12. }
    13. class Circle implements IShape{
    14. @Override
    15. public void draw() {
    16. System.out.println("绘制一个圆");
    17. }
    18. }
    19. //共享所有的IShape类型的对象,当需要使用IShape对象时,从对象池中获取一个即可,不是临时创建
    20. //当不需要使用对象时,不是直接释放对象,而是归还对象池
    21. class ObjectManager{
    22. private static IShape[] arr=new IShape[20];
    23. static { //类加载完毕,则在对象池中已经准备了20个对象
    24. for(int i=0;i
    25. arr[i]=new Circle();
    26. }
    27. }
    28. //当需要使用对象时,从对象池中获取一个对象即可
    29. public static IShape getInstance() {
    30. IShape res=null;
    31. for(int i=arr.length-1;i>=0;i--) {
    32. res=arr[i];
    33. if(res!=null) {
    34. arr[i]=null;
    35. break;
    36. }
    37. }
    38. return res;
    39. }
    40. //当不使用对象时,需要归还到对象池中,以供下次需要时再次使用
    41. public static void relessInstance(IShape obj) {
    42. for(int i=0;i
    43. IShape tmp=arr[i];
    44. if(tmp==null) {
    45. arr[i]=obj;
    46. break;
    47. }
    48. }
    49. }
    50. }

    使用ExecutorService、Callable、Future实现有返回结果的线程,线程池的具体实现实际上是依赖于ThreadPoolExecutor

    1. public class Test40 {
    2. public static void main(String[] args) {
    3. //固定大小的线程池,容积为3
    4. // ExecutorService es=Executors.newFixedThreadPool(3);
    5. //缓存线程池
    6. ExecutorService es=Executors.newCachedThreadPool();
    7. FutureTask[] fs=new FutureTask[10];
    8. for(int i=1;i<=10;i++) {
    9. int begin=(i-1)*100+1;
    10. int end=i*100;
    11. fs[i-1]=new FutureTask<>(new Callable() {
    12. public Integer call() throws Exception {
    13. System.out.println(Thread.currentThread());
    14. int res=0;
    15. for(int k=begin;k<=end;k++)
    16. res+=k;
    17. return res;
    18. }
    19. });
    20. es.submit(fs[i-1]);
    21. }
    22. int res=0;
    23. for(Future f:fs) {
    24. try {
    25. res+=f.get(1, TimeUnit.SECONDS);
    26. } catch (InterruptedException | ExecutionException | TimeoutException e) {
    27. e.printStackTrace();
    28. }
    29. }
    30. System.out.println(res);
    31. }
    32. }

    线程池的好处

    • 重用存在的线程,减少对象创建、消亡的开销,性能佳
    • 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞
    • 提供定时执行、定期执行、单线程、并发数控制等功能。

    线程池的工作原理

    1. 线程池判断核心线程池里的线程是否都在执行任务。如果不是,则创建一个新的工作线程来执行任务。如果核心线程池里的线程都在执行任务,则执行第二步。
    2. 线程池判断工作队列是否已经满。如果工作队列没有满,则将新提交的任务存储在这个工作队列里进行等待。如果工作队列满了,则执行第三步
    3. 线程池判断线程池的线程是否都处于工作状态。如果没有,则创建一个新的工作线程来执行任务。如果已经满了,则交给饱和策略来处理这个任务

     其构造函数如下:

    public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,  long  keepAliveTime,TimeUnit unit, BlockingQueue workQueue)

  • 相关阅读:
    2-31 基于matlab的微表情识别
    串口数据包收发
    .NET Conf 2022 11 月 8 日至 10 日 正式开启
    第一个Shader程序
    BioVendor sRAGE蛋白解决方案
    学习笔记|ADC反推电源电压|扫描按键(长按循环触发)|课设级实战练习|STC32G单片机视频开发教程(冲哥)|第十八集:ADC实战
    基于PLC的矿泉水自动瓶装控制系统设计
    第5章:传输层
    如何降低海康、大华等网络摄像头调用的高延迟问题(一):海康威视网络摄像头的python sdk使用(opencv读取sdk流)
    基于深度学习的图书管理推荐系统(python版)
  • 原文地址:https://blog.csdn.net/tiger_root/article/details/126393273