带你通俗易懂的理解——线程、多线程与线程池

JavaSE个人复习式整理知识点之异常、线程 异常、线程1 异常1.1 异常概念1.2 异常体系1.3 异常分类1.4 异常的产⽣过程解析2 异常的处理2.1 抛出异常throw2.2 Objects⾮空判断2.3 声明异常throws 1 异常 1.1 异常概念 异常,就是不正常的意思。在⽣活中:医⽣说,你的身体某个部位有异常,该部位和正常相⽐有点不同,该部位的功能将受影响。在程序中的意思就是: 异常 :指的是程序在执⾏过程中,出现的⾮正常的情况,最终会导致JVM的⾮正常停⽌。 在Java等⾯向对象的编程语⾔中,异常本身是⼀个类,产⽣异常就是创建 阅读详情

进程与线程

  • 进程:进程就是正在执行的程序。

  • 线程:是程序执行的一条路径, 一个进程中可以包含多条线程。
    通俗理解:例如你打开微信就是打开一个进程,在微信里面和好友视频聊天就是开启了一条线程。

  • 两者之间的关系:
    一个进程里面可以有多条线程,至少有一条线程。
    一条线程一定会在一个进程里面。

关于进程与线程的讲解,这篇文章讲的挺好的-->进程与线程的一个简单解释 http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html

创建线程的三种方式

一、继承Thread

1、定义一个类MyThread继承Thread,并重写run方法。
2、将要执行的代码写在run方法中。
3、创建该类的实例,并调用start()方法开启线程。


代码如下:

public class MainActivity extends AppCompatActivity {
    private final String TAG = this.getClass().getSimpleName();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //3、创建该类的实例,并调用start()方法开启线程。
        MyThread myThread = new MyThread();
        myThread.start();
    }
    //1、定义一个类MyThread继承Thread,并重写run方法。
    class MyThread extends Thread {
        public void run() {
            //2、将执行的代码写在run方法中。
            for (int i = 0; i < 100; i++) {
                Log.d(TAG, "线程名字:" + Thread.currentThread().getName()  + "  i=" + i);
            }
        }
    }
}

二、实现Runnable接口

1、定义一个类MyRunnable实现Runnable接口,并重写run方法。
2、将要执行的代码写在run方法中。
3、创建Thread对象, 传入MyRunnable的实例,并调用start()方法开启线程。


代码如下:

public class MainActivity extends AppCompatActivity {
    private final String TAG = this.getClass().getSimpleName();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //3、创建Thread对象, 传入MyRunnable的实例,并调用start()方法开启线程。
        Thread thread = new Thread(new MyRunnable());
        thread.start();
    }
    //1、定义一个类MyRunnable实现Runnable接口,并重写run方法。
    class MyRunnable implements Runnable {
        public void run() {
            //2、将执行的代码写在run方法中。
            for (int i = 0; i < 100; i++) {
                Log.d(TAG, "线程名字:" + Thread.currentThread().getName() + "  i=" + i);
            }
        }
    }
}

三、实现 Callable 接口

Callable 是类似于 Runnable 的接口,实现 Callable 接口的类和实现 Runnable 的类都是可被其它线程执行的任务。

1、自定义一个类 MyCallable 实现 Callable 接口,并重写call()方法
2、将要执行的代码写在call()方法中
3、创建线程池对象,调用submit()方法执行MyCallable任务,并返回Future对象
4、调用Future对象的get()方法获取call()方法执行完后的值


代码如下:

public class MainActivity extends AppCompatActivity {
    private final String TAG = this.getClass().getSimpleName();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //3、创建线程池对象,调用submit()方法执行MyCallable任务,并返回Future对象
        ExecutorService pool = Executors.newSingleThreadExecutor();
        Future<Integer> f1 = pool.submit(new MyCallable());
        //4、调用Future对象的get()方法获取call()方法执行完后的值
        try {
            Log.d(TAG, "sum=" + f1.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        //关闭线程池
        pool.shutdown();
    }
    //1、自定义一个类MyCallable实现Callable接口,并重写call()方法
    public class MyCallable implements Callable<Integer> {
        @Override
        public Integer call() throws Exception {
            //2、将要执行的代码写在call()方法中
            int sum = 0;
            for (int i = 0; i <= 100; i++) {
                sum += i;
            }
            return sum;
        }
    }
}

 

创建线程的三种方式对比

一、继承 Thread 类与实现 Runnable 接口的区别

我们都知道 java 支持单继承,多实现。实现 Runnable 接口还可以继承其他类,而使用继承 Thread 就不能继承其他类了。所以当你想创建一个线程又希望继承其他类的时候就该选择实现 Runnable 接口的方式。

二、实现 Callable 接口与 Runnable 接口的区别

Callable 执行的方法是 call() ,而 Runnable 执行的方法是 run()。
call() 方法有返回值还能抛出异常, run() 方法则没有没有返回值,也不能抛出异常。

多线程

一、概念

一个进程中开启了不止一个线程。

二、多线程的优缺点

  • 优点
    1、提高CPU的使用率
    例如朋友圈发表图片,当你上传9张图片的时候,如果开启一个线程用同步的方式一张张上传图片,假设每次上传图片的线程只占用了CPU 1%d的资源,剩下的99%资源就浪费了。但是如果你开启9个线程同时上传图片,CPU就可以使用9%的资源了。
    2、提高程序的工作效率
    还是拿朋友圈发表图片来说,假设开启一个线程上传一张图片的时间是1秒,那么同步的方式上传9张就需要9秒,但是你开启9个线程同时上传图片,那么就只需要1秒就完成了。

  • 缺点
    1、如果有大量的线程,会影响性能,因为CPU需要在它们之间切换。
    2、更多的线程需要更多的内存空间。
    3、多线程操作可能会出现线程安全或者死锁等问题。

三、多线程并行和并发的区别

  • 概念
    并行:多个处理器或者多核处理器同时执行多个不同的任务。
    并发:一个处理器处理多个任务。

  • 打个比喻
    并行就是一个人用他的左手喂女儿吃饭,同时用右手喂儿子吃饭。
    并发就是一个人先喂女儿吃一口饭,接着喂儿子吃一口,然后再喂女儿吃一口,轮流喂。

  • 举个多线程并发操作同一数据出现线程安全的例子
    利用多线程上传9张图片,并提示还剩几张图片未上传。代码如下:

public class MainActivity extends AppCompatActivity {
    private final String TAG = this.getClass().getSimpleName();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //开启2条线程上传图片
        MyRunnable myRunnable = new MyRunnable();
        new Thread(myRunnable, "线程1").start();
        new Thread(myRunnable, "线程2").start();
    }
    public class MyRunnable implements Runnable {
        private int imgNum = 9;//图片数量
        @Override
        public void run() {
            while (true) {
                if (imgNum == 0) {
                    break;
                }
                try {
                    Thread.sleep(1000);//模拟上传一张图片需要1秒钟的时间
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Log.d(TAG, Thread.currentThread().getName() + "正在上传图片...,还剩" + imgNum-- + "张图片未上传");
            }
        }
    }
}

打印结果如下:

由图可知,图片数量出现了负数,显然是错误的。

原因:
出现这种错误的原因是有多个线程在操作共享的数据。即一个线程在操作共享数据的过程中CPU切换到其他线程又对该数据进行操作,这就是所谓的多线程并发。

解决:
把操作数据的那段代码用 synchronized 进行同步, 这样就能保证在同一时刻只能有一个线程能够访问。


代码如下:

public class MainActivity extends AppCompatActivity {
    private final String TAG = this.getClass().getSimpleName();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //开启2条线程上传图片
        MyRunnable myRunnable = new MyRunnable();
        new Thread(myRunnable, "线程1").start();
        new Thread(myRunnable, "线程2").start();
    }
    public class MyRunnable implements Runnable {
        private int imgNum = 9;//图片数量
        @Override
        public void run() {
            while (true) {
                synchronized (MyRunnable.class) { //加上synchronized进行同步,保证在同一时刻只能有一个线程能够访问。
                    if (imgNum == 0) {
                        break;
                    }
                    try {
                        Thread.sleep(1000);//模拟上传一张图片需要1秒钟的时间
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Log.d(TAG, Thread.currentThread().getName() + "正在上传图片...,还剩" + imgNum-- + "张图片未上传");
                }
            }
        }
    }
}

打印结果如下:

线程池

关于线程池

前面举的朋友圈发表图片的多线程例子中,为了提高CPU的使用率和程序的工作效率就需要创建9个线程来上传图片。但是线程的创建和销毁是非常耗CPU和内存的,因为它涉及到要与操作系统进行交互。这样就可能导致创建与销毁线程的开销比实际业务还大,而线程池就能很好的解决这些问题。线程池里的每一个线程结束后,并不会销毁(可以设置超时销毁),而是回到线程池中成为空闲状态,等待下一个对象来使用。

使用线程池的优点

1、减少创建与销毁线程带来的性能开销。
2、可控制最大并发线程数,避免过多资源竞争而导致系统内存消耗完。
3、能更好的控制线程的开启与回收,并且能定时执行任务。

线程池中重要的几个类

  • Executor:java中线程池的顶级接口,可以称它为一个执行器,通过查看源码也知道,他只有一个简单的方法execute(Runnable command),就是用来执行提交的任务。源码如下:
    【Executor.java】

public interface Executor {
    void execute(Runnable command);
}
  • ExecutorService:Executor的子类,也是真正的线程池接口。它提供了提交任务和关闭线程池等方法。调用submit方法提交任务还可以返回一个Future对象,利用该对象可以了解任务执行情况,获得任务的执行结果或取消任务。

  • Executors:由于线程池配置比较复杂,自己配置的线程池可能性能不是最好的。Executors就是用来方便创建各种常用线程池的工具类。

  • ThreadPoolExecutor:ExecutorService的默认实现,Executors创建各种线程池的时候内部其实就是调用了ThreadPoolExecutor的构造方法。下面通过查看源码验证。
    例如随便创建一个线程池:

ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();

点击newCachedThreadPool()进去,里面确实调用了ThreadPoolExecutor的构造方法,如下:
【Executor.java】

    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

ThreadPoolExecutor构造函数参数说明

下面从源码中拿一个参数最完整的来讲解,如下:
【ThreadPoolExecutor.java】

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
    }
  • corePoolSize:核心线程数,如果运行的线程数少于corePoolSize,当有新的任务过来时会创建新的线程来执行这个任务,即使线程池中有其他空闲的线程。

  • maximumPoolSize:线程池中允许的最大线程数。

  • keepAliveTime:如果线程数多于核心线程数,那么这些多出来的线程如果空闲时间超过keepAliveTime将会被终止。

  • unit:keepAliveTime参数的时间单位。

  • workQueue:任务队列,通过线程池的execute方法会将任务Runnable存储在队列中。

  • threadFactory:线程工厂,用来创建新线程。

  • handler:添加任务出错时的策略捕获器,默认是ThreadPoolExecutor.AbortPolicy ,即添加任务出错就直接抛出异常 。

四种线程池

  • newFixedThreadPool:创建固定大小的线程池,这样可以控制线程最大并发数,超出的线程会在队列中等待。如果线程池中的某个线程由于异常而结束,线程池则会再补充一条新线程。
    例子:创建线程数为3的线程池

        ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(3);
        for (int i = 0; i < 10; i++) {
            final int finalI = i;
            newFixedThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(1000);
                        Log.d(TAG, "线程名字:" + Thread.currentThread().getName() + "  i=" + finalI);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }

打印结果:

由打印结果可知,10个任务始终在3个线程中执行。

  • newSingleThreadExecutor:创建一个单线程的线程池,即这个线程池永远只有一个线程在运行,这样能保证所有任务按指定顺序来执行。如果这个线程异常结束,那么会有一个新的线程来替代它。


    例子:

        ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 10; i++) {
            final int finalI = i;
            newSingleThreadExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(1000);
                        Log.d(TAG, "线程名字:" + Thread.currentThread().getName() + "  i=" + finalI);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }

打印结果:

由打印结果可知,10个任务始终在3个线程中执行。

  • newCachedThreadPool:创建带有缓存的线程池,在执行新的任务时,当线程池中有之前创建的可用线程就重用之前的线程,否则就新建一条线程。如果线程池中的线程在60秒未被使用,就会将它从线程池中移除。
    例子:

        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            final int finalI = i;
            newCachedThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    Log.d(TAG, "线程名字:" + Thread.currentThread().getName() + "  i=" + finalI);
                }
            });
        }

 

由打印结果可知,线程1出现了很多次,说明有重用之前创建的线程。

  • newScheduledThreadPool:创建定时和周期性执行的线程池。

        ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(3);
        /**
         * 延迟2秒执行任务
         */
        newScheduledThreadPool.schedule(new Runnable() {
            @Override
            public void run() {
                Log.d(TAG, "线程名字:" + Thread.currentThread().getName() + "定时任务");
            }
        }, 2, TimeUnit.SECONDS);
        /**
         * 延迟1秒后每2秒执行一次任务
         */
        newScheduledThreadPool.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                Log.d(TAG, "线程名字:" + Thread.currentThread().getName() + "周期性任务");
            }
        }, 1, 2, TimeUnit.SECONDS);

 

由打印结果可知,定时任务是 2 秒后执行任务,周期性任务是延迟 1 秒后每 2 秒执行一次任务。

线程池详解(通俗易懂超级好) 目标 【理解】线程池基本概念 【理解】线程池工作原理 【掌握】自定义线程池 【应用】java内置线程池 【应用】使用java内置线程池完成综合案例 线程池 线程池基础 线程池使用 线程池综合案例 4.学员练习 5.线程池总结 概念介绍 1:什么是线程池 2:为什么使用线程池 3:线程池有哪些优势 什么是池 什么是线程池 线程池其实就是一种多线程处理形式,处理过程中可以将任务添加到队列中,然后在创建线程后自动启动这些任务。这里的线程就是我们前面学过的线程,这里的任务就是我们前面学过的实现了Runna. 阅读详情

相关推荐

JVM 线程池的原理与使用:Java 多线程开发利器

在 Java 多线程开发中,“新建线程处理任务”看似简单,实则暗藏隐患:频繁创建/销毁线程会消耗大量 CPU 资源(就像反复开关电灯浪费电能),线程数量失控可能导致系统崩溃(就像餐厅服务员太多挤成一团)。本文将聚焦 JVM 线程池(),覆盖其核心原理、参数配置、实战用法及避坑指南,帮助开发者从“会用”到“精通”。用餐厅管理订单类比线程池运行核心概念(工作线程、任务队列、拒绝策略)的通俗解释线程池工作流程的 Mermaid 流程图手动创建线程池的 Java 代码示例与参数详解。

Java大师兄的博客 972

什么是线程?线程概念及方法详细讲解

什么是线程?线程概念及方法详细讲解

leizi146的博客 6588

精易VS鱼刺线程池效果对比源码-易语言

精易VS鱼刺线程池效果对比源码

线程(线程基本概念、java实现多线程、使用多线程、线程的生命周期、线程同步、线程死锁)

线程(线程基本概念、java实现多线程、使用多线程、线程的生命周期、线程同步、线程死锁)

H215919719的博客 9561

多线程写法(精易模块线程池和鱼刺模块线程池)

源码演示了多线程写法,主要是对比精易模块线程池,鱼刺模块线程池。@在人间。

CIC-IDS-2018数据集高效预处理实战:从数据清洗到特征整合

本文详细介绍了CIC-IDS-2018数据集的高效预处理方法,从数据清洗到特征整合的全流程实战。通过内存优化、异常值处理和特征工程等技巧,帮助网络安全研究人员快速处理大规模网络流量数据,提升机器学习模型的训练效率和准确率。特别针对特征数据的预处理提供了实用代码示例和优化建议。

weixin_29274969的博客 502

通俗易懂的java多线程(又干货又可爱哦)

初入江湖的小李,在见识了“南慕容,北乔峰”的飒爽英姿之后,就励志成为一位武林高手。 小李开始了日复一日的修炼,然而在修炼了一年之后,小李的进境缺很慢,小李百思不得其解,正在恼怒之际,一位仙风道骨的老人传授他一门心法,名叫“多线程”,这门功法的强大之处就在于可以分心多用,同时修炼多种功法,这样一来,小李的进境就很快。 然而,这门心法缺有一个很大的缺陷,“线程同步问题”,就是在运行心法的时,如果多门功法需要同时使用

专注技术 4526

pynq-z2 HLS开发

定制Overlay一.用HLS生成一个定制IP功啊啊是合理的创建标题,有助于目录的生成如何改变是式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 一.用HLS生成一个定制IP ...

qq_38769280的博客 4156

Java中的多线程如何理解——精简

通过前面的学习,我们已经学会了线程是如何创建的以及线程的常用方法,接下来呢,我们将要深入性了解线程中的知识,主要是线程安全,线程同步,线程池三个知识点。我相信大家通过这节课的简单地学习,就可以大概地掌握了线程吧!好了,废话不多说,我们开始今天的学习吧!......

weixin_50635856的博客 4632

颠覆性创新的测量框架与跨领域实证分析

颠覆性创新作为科技发展的重要驱动力,其核心在于实现知识体系的范式转换。从技术原理看,这类创新通常具备知识替代、网络重构和跨领域渗透三大特征,通过引用网络分析和文本挖掘等方法可量化评估其影响力。在工程实践中,CD指数、DI指数等测量工具帮助研究者识别具有突破潜力的成果,而深度学习等新兴技术进一步提升了评估精度。当前AI、半导体等领域的热门技术发展表明,模块化架构和产业协同能有效促进颠覆性创新。面对全球范围内创新颠覆性下降的趋势,优化科研评价体系、构建跨学科协作网络成为关键应对策略。

weixin_29735807的博客 321

从网格剖分到结果外推:一文拆解HFSS快速扫频(Fast Sweep)的底层逻辑与性能调优

本文深入解析了HFSS快速扫频(Fast Sweep)技术的底层逻辑与性能调优方法。通过ALPS算法实现频带外推,快速扫频相比离散扫频和插值扫频能提升3-5倍计算效率,特别适用于天线阵列、微波滤波器等宽频带分析场景。文章详细介绍了算法架构、参数优化策略及工程实践中的精度保障机制,帮助工程师高效完成电磁仿真。

weixin_28693447的博客 92

通俗易懂理解线程池【01】

线程池

localhost65535的博客 749

程序化广告行业(23/89):深度剖析广告效果评估指标

大家好,我一直希望能和大家一起在技术领域不断探索、共同进步。在之前的文章中,我们了解了程序化广告中腾讯的业务布局和广告效果评估的基础概念,今天让我们进一步深入剖析广告效果评估的各项指标,这对理解程序化广告的运作机制至关重要

yyy173611的博客 4863

你通俗易懂的理解——线程、多线程与线程池

(2)解决思路:保证一个线程a在操作ticket的过程中,其它线程必须等待,知道线程a操作ticket结束以后,其它线程才可以操作共享数据。需要被同步的代码,在被synchronized包裹以后,就使得一个线程在操作这些代码的过程中,其它线程必须等待。抓的过程,生成异常类对象后将对象抛出,程序不执行其后代码。同步监视器:俗称锁,哪些线程获取了锁,哪个线程就能执行需要被同步的代码。程序是一段代码,进程是程序的执行过程(从创建到使用到消亡),线程。使用线程同步机制(同步代码块或同步方法)

fanTuanye的博客 1214

易盾滑块的js逆向分析

基于易盾的滑块验证码进行逆向分析,最种实现全系列的验证码逆向,包括滑块、点选、推理拼图等多种类型。

shanf7921的博客 3万+

【WRF安装】WRF编译错误:problems building executables look for error in the build log

WRF编译错误:problems building executables look for error in the build log

WW、forever的博客 752

多线程(通俗易懂,一篇就够了)

while(!isQuit) {System.out.println("线程工作中");try {System.out.println("线程工作完毕");});t.start();System.out.println("设置isQuit 为true");//thread类内部,有一个现成的标志位,可以用来判定当前的循环是否要结束while(!System.out.println("线程工作中");try {break;});t.start();try {

2202_75439262的博客 3787

【图像超分】论文复现:经典超分 | SAN的Pytorch源码复现,跑通源码,适配高版本的python/pytorch/cuda,使用EDSR-PyTorch进行训练和测试

本文介绍了单幅图像超分辨率重建方法SAN(二阶注意网络)的代码实现。文章详细说明了在高版本Python/Pytorch环境下适配SAN源码的方法,并提供了修改后的完整代码和预训练模型下载链接。 主要亮点包括: 将SAN模型实现整合到EDSR-Pytorch框架中,解决了高版本环境下的兼容性问题 提供了完整的数据集准备指南(DIV2K训练集和5个测试集) 给出了详细的测试命令,涵盖x2、x3、x4不同放大倍率 公开了预训练模型和可视化结果的下载资源 提供了修改后的适配高版本环境的代码。

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 1412

通俗易懂带你了解Java多线程处理

何夜息随笔录-多线程的使用 进程和线程 首先需要分清进程和线程,进程是系统分配的单位,就是任务管理器可以看到的进程,这是由系统自动分配和管理的,每个进程都有进程PID。 线程就是程序的一块逻辑,这是我们通过代码去创建的,我们可以操作多个进程,程序运行的时候就会吧线程自动放到进程中去执行。 一个进程可以包括多个线程!线程是CPU执行和调度的单位。 线程的创建 首先是使用继承Thread类,然后重写run方法,然后调用start方法执行线程。 然后看源码可以发现,这个被继承的Thread类,其实是实现了Runn

何夜息的博客 473

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

【QT开发日志】QT多线程编程:实现高效的多线程应用

在当今的软件开发领域,用户对应用程序的性能和响应速度要求越来越高。尤其是在处理复杂任务、大量数据或进行网络通信时,单线程往往难以满足需求,容易出现界面卡顿、操作无响应等问题,严重影响用户体验。

鸽芷咕的博客 9776

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

从根上理解高性能、高并发(一):深入计算机底层,理解线程与线程池

本文原题“聊聊TCP连接耗时的那些事儿”,本次收录已征得作者同意,转载请联系作者。有少许改动。 1、系列文章引言 1.1 文章目的 作为即时通讯技术的开发者来说,高性能、高并发相关的技术概念早就了然与胸,什么线程池、零拷贝、多路复用、事件驱动、epoll等等名词信手拈来,又或许你对具有这些技术特征的技术框架比如:Java的Netty、Php的workman、Go的nget等熟练掌握。但真正到了面视或者技术实践过程中遇到无法释怀的疑惑时,方知自已所掌握的不过是皮毛。 返璞归真、回归本质,这些技术特征背

hellojackjiang2011的博客 928

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

上一篇: java删除指定目录下一小时前生成的文件
下一篇: git生成SSH KEY公钥
rmnjava
博客等级 码龄20年 8粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值