精华内容
下载资源
问答
  • java 多线程使用线程池 什么是线程? (What is a Thread?) A thread is a lightweight process. Any process can have multiple threads running in it. 线程是轻量级进程。 任何进程都可以在其中运行多个线程。 ...

    java 多线程使用线程池

    什么是线程? (What is a Thread?)

    A thread is a lightweight process. Any process can have multiple threads running in it.

    线程是轻量级进程。 任何进程都可以在其中运行多个线程。

    For example in a web browser, we can have one thread which will load the user interface and another thread which will actually retrieve all the data that needs to be displayed in that interface.

    例如,在Web浏览器中,我们可以有一个线程将加载用户界面,而另一个线程将实际检索需要在该界面中显示的所有数据。

    什么是多线程? (What is MultiThreading?)

    Multithreading enables us to run multiple threads concurrently.

    多线程使我们能够同时运行多个线程。

    For example in a web browser, we can have one thread which handles the user interface, and in parallel we can have another thread which fetches the data to be displayed.

    例如,在Web浏览器中,我们可以有一个线程来处理用户界面,而并行地,我们可以有另一个线程来获取要显示的数据。

    So multithreading improves the responsiveness of a system.

    因此,多线程可提高系统的响应能力。

    什么是并发? (What is Concurrency?)

    Concurrency in the context of threads enables us to run multiple threads at the same time.

    线程上下文中的并发性使我们可以同时运行多个线程。

    But do the threads really run at the same time?

    但是这些线程真的同时运行吗?

    单核系统 (Single Core Systems)

    The Thread Scheduler provided by the JVM decides which thread runs at any given time. The scheduler gives a small time slice to each thread.

    JVM提供的线程计划程序决定在任何给定时间运行哪个线程。 调度程序为每个线程分配了一小段时间。

    So at any given time we have only one thread which is actually running in the processor. But because of the time slicing we get the feeling that multiple threads are running at the same time.

    因此,在任何给定时间,我们只有一个线程在处理器中实际运行。 但是由于时间片,我们感觉到多个线程正在同时运行。

    多核系统 (Multi Core Systems)

    Even in multiple core systems the thread scheduler is involved. But since we have multiple cores, we can actually have multiple threads running at the exact same time.

    即使在多核系统中,也要使用线程调度程序。 但是,由于我们有多个内核,因此实际上我们可以在完全相同的时间运行多个线程。

    For example if we have a dual core system, then we can have 2 threads running at the exact same time. The first thread will run in the first core, and the second thread will run in the second core.

    例如,如果我们有一个双核系统,那么我们可以有两个线程同时运行。 第一个线程将在第一个内核中运行,第二个线程将在第二个内核中运行。

    为什么需要多线程? (Why is Multithreading needed?)

    Multithreading enables us to improve the responsiveness of a system.

    多线程使我们能够改善系统的响应能力。

    For example in a web browser, if everything ran in a single thread, then system would be completely unresponsive whenever data was being fetched to display. For example, if it takes 10 seconds to fetch the data, then in that 10 seconds we wont be able to do anything else in the web browser like opening new tabs, or even closing the web browser.

    例如,在Web浏览器中,如果所有内容都在单个线程中运行,那么只要提取数据以进行显示,系统就会完全无响应。 例如,如果获取数据需要10秒钟,那么在那10秒钟内,我们将无法在Web浏览器中执行其他任何操作,例如打开新标签页,甚至关闭Web浏览器。

    So running different parts of a program in different threads concurrently helps improve the responsiveness of a system.

    因此,在不同线程中同时运行程序的不同部分有助于提高系统的响应能力。

    如何用Java编写多线程程序 (How to write Multithreaded Programs in Java)

    We can create threads in Java using the following

    我们可以使用以下代码在Java中创建线程

    • Extending the thread class

      扩展线程类
    • Implementing the runnable interface

      实施可运行接口
    • Implementing the callable interface

      实现可调用的接口
    • By using the executor framework along with runnable and callable tasks

      通过使用执行程序框架以及可运行和可调用的任务

    We will look at callables and the executor framework in a separate blog. In this article I will be mainly focussing on extending the thread class and implementing the runnable interface.

    我们将在单独的博客中介绍可调用对象和执行程序框架。 在本文中,我将主要集中于扩展线程类和实现可运行接口。

    扩展线程类 (Extending the Thread Class)

    In order to create a piece of code which can be run in a thread, we create a class and then extend the thread class. The task being done by this piece of code needs to be put in the run() function.

    为了创建可以在线程中运行的代码,我们创建一个类,然后扩展该线程类。 由这段代码完成的任务需要放在run()函数中。

    In the below code you can see that worker is a class which extends the thread class, and the task of printing numbers 0 to 5 is being done inside the run() function.

    在下面的代码中,您可以看到worker是扩展线程类的类,并且在run()函数中完成了打印数字0至5的任务。

    class Worker extends Thread {
    
    	@Override
    	public void run() {
    		for (int i = 0; i <= 5; i++) {
    			System.out.println(Thread.currentThread().getName() + ": " + i);
    		}
    	}
    
    }

    In the above code Thread.currentThread().getName() is used to get the name of the current thread which is running the code.

    在上面的代码中, Thread.currentThread()。getName()用于获取运行代码的当前线程的名称。

    In order to create a thread, we just need to create an instance of the worker class. And then we can start the thread using the start() function.

    为了创建线程 ,我们只需要创建worker类的实例。 然后,我们可以使用start()函数启动线程。

    public class ThreadClassDemo {
    	public static void main(String[] args) {
    		Thread t1 = new Worker();
    		Thread t2 = new Worker();
    		Thread t3 = new Worker();
    		t1.start();
    		t2.start();
    		t3.start();
    
    	}
    }

    In the above code, we are creating 3 threads (t1,t2 and t3) from the worker class. Then we are starting the threads using the start() function.

    在上面的代码中,我们从worker类创建3个线程(t1,t2和t3)。 然后,我们使用start()函数启动线程。

    Here is the final code for creating a thread by extending a thread class:

    这是通过扩展线程类创建线程的最终代码:

    class Worker extends Thread {
    
    	@Override
    	public void run() {
    		for (int i = 0; i <= 5; i++) {
    			System.out.println(Thread.currentThread().getName() + ": " + i);
    		}
    	}
    
    }
    
    public class ThreadClassDemo {
    	public static void main(String[] args) {
    		Thread t1 = new Worker();
    		Thread t2 = new Worker();
    		Thread t3 = new Worker();
    		t1.start();
    		t2.start();
    		t3.start();
    
    	}
    }

    Here is the output we get by running the above code:

    这是通过运行上面的代码获得的输出:

    You can see that all the 3 threads have printed the numbers from 0 to 5.

    您可以看到所有3个线程都已打印从0到5的数字。

    You can also clearly see from the output that the 3 threads do not run in any particular sequence

    您还可以从输出中清楚地看到3个线程没有按任何特定顺序运行

    实施可运行接口 (Implementing the Runnable Interface)

    In order to create a piece of code which can be run in a thread, we create a class and then implement the runnable interface. The task being done by this piece of code needs to be put in the run() function.

    为了创建可以在线程中运行的代码,我们创建一个类,然后实现可运行接口。 由这段代码完成的任务需要放在run()函数中。

    In the below code you can see that RunnableWorker is a class which implements runnable interface, and the task of printing numbers 0 to 4 is being done inside the run() function.

    在下面的代码中,您可以看到RunnableWorker是实现runnable接口的类,并且在run()函数内部完成了打印数字0至4的任务。

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

    In order to create a thread, first we need to create an Instance of RunnableWorker which implements the runnable interface.

    为了创建一个线程,首先我们需要创建RunnableWorker的实例,实现Runnable接口。

    Then we can create a new thread by creating an instance of the thread class and passing the instance of RunnableWorker as the argument. This is shown in the code below:

    然后,我们可以通过创建线程类的实例并将RunnableWorker的实例作为参数来创建新线程。 如下代码所示:

    public class RunnableInterfaceDemo {
    
    	public static void main(String[] args) {
    		Runnable r = new RunnableWorker();
    		Thread t1 = new Thread(r);
    		Thread t2 = new Thread(r);
    		Thread t3 = new Thread(r);
    		
    		t1.start();
    		t2.start();
    		t3.start();
    
    	}
    
    }

    The above code creates a runnable instance r. Then it create 3 threads (t1, t2 and t3) and passes r as the argument to the 3 threads. Then the start() function is used to start all 3 threads.

    上面的代码创建了一个可运行实例r。 然后,它创建3个线程(t1,t2和t3),并将r作为参数传递给3个线程。 然后使用start()函数启动所有3个线程。

    Here is the complete code for creating a thread by implementing the runnable interface:

    这是用于通过实现runnable接口创建线程的完整代码:

    class RunnableWorker implements Runnable{
    
    	@Override
    	public void run() {
    		for (int i = 0; i <= 4; i++) {
    			System.out.println(Thread.currentThread().getName() + ": " + i);
    		}
    	}
    	
    }
    
    public class RunnableInterfaceDemo {
    
    	public static void main(String[] args) {
    		Runnable r = new RunnableWorker();
    		Thread t1 = new Thread(r);
    		Thread t2 = new Thread(r);
    		Thread t3 = new Thread(r);
    		
    		t1.start();
    		t2.start();
    		t3.start();
    
    	}
    
    }

    On running the above code, we will get the following output. The sequence of the output will change every time the code is run.

    运行上面的代码后,我们将获得以下输出。 每次运行代码时,输​​出顺序都会改变。

    Implementing the runnable interface is a better option than extending the thread class since we can extend only one class, but we can implement multiple interfaces in Java.

    与只能扩展一个线程类相比,实现可运行接口是更好的选择,因为我们只能扩展一个类,但是我们可以在Java中实现多个接口。

    Java 8中的可运行接口 (Runnable Interface in Java 8)

    In Java 8, the runnable interface becomes a FunctionalInterface since it has only one function, run().

    在Java 8中,由于可运行接口只有一个函数run() ,因此它成为FunctionalInterface

    The below code shows how we can create a runnable instance in Java 8.

    以下代码显示了我们如何在Java 8中创建可运行实例。

    public class RunnableFunctionalInterfaceDemo {
    
    	public static void main(String[] args) {
    		
    		Runnable r = () -> {
    			for (int i = 0; i <= 4; i++) {
    				System.out.println(Thread.currentThread().getName() + ": " + i);
    			}
    		};
    		
    		Thread t1 = new Thread(r);
    		Thread t2 = new Thread(r);
    		Thread t3 = new Thread(r);
    		
    		t1.start();
    		t2.start();
    		t3.start();
    	}
    
    }

    Here, instead of creating a class and then implementing the runnable interface, we can directly use a lambda expression to create a runnable instance as shown below:

    在这里,我们可以直接使用lambda表达式创建一个可运行的实例,而不是创建一个类然后再实现可运行的接口,如下所示:

    Runnable r = () -> {
            for (int i = 0; i <= 4; i++) {
                System.out.println(Thread.currentThread().getName() + ": " + i);
            }
        };

    (Code)

    The code in this article is available in the following GitHub repo: https://github.com/aditya-sridhar/basic-threads-demo

    以下GitHub存储库中提供了本文中的代码: https : //github.com/aditya-sridhar/basic-threads-demo

    恭喜😃 (Congrats 😃)

    You now know how to create threads by extending the thread class and by implementing the runnable interface.

    现在,您知道如何通过扩展线程类并实现可运行接口来创建线程。

    I will discuss the thread life cycle and challenges while using threads in my next blog post.

    我将在下一篇博客文章中讨论使用线程时的线程生命周期和挑战。

    My Website: https://adityasridhar.com/

    我的网站https : //adityasridhar.com/

    随时在LinkedIn上与我联系或在Twitter上关注我 (Feel free to connect with me on LinkedIn or follow me on Twitter)

    翻译自: https://www.freecodecamp.org/news/how-to-get-started-with-multithreading-in-java/

    java 多线程使用线程池

    展开全文
  • 线程池 spring内置了ThreadPoolTaskExecutor线程池,可以直接初始化后声明为bean,在上下文的任意位置进行依赖注入。 线程实例的方法 如果你的线程不需要返回值,可以调用ThreadPoolTaskExecutor bean实例的execute...

    线程池 ThreadPoolTaskExecutor

    spring内置了ThreadPoolTaskExecutor线程池,可以直接初始化后声明为bean,在上下文的任意位置进行依赖注入。

    线程实例的方法 execute/submit

    如果你的线程不需要返回值,可以调用ThreadPoolTaskExecutor bean实例的execute方法,
    如果需要返回值,可以调用submit方法。

    示例

    假设ThreadPoolTaskExecutor 的bean名称为 pool,则一个简单的线程执行实例为:
    Future future=pool.submit(()=>doMyJob() );
    有了lamda表达式,就是这么简单,其实lamda表达式中是创建了一个 Callable接口的匿名内部类。并且执行了在线程外面声明的doMyJob()方法。就是这么简单…

    			 //异步方式查询
                try {
                    Future<Map<String, Object>> bInfoFuture = threadPoolTaskExecutor.submit(() -> getCaseInfoByCaseids(caseids));
                    Future<Map<String, Object>> bInfothFuture = threadPoolTaskExecutor.submit(() -> getCaseInfothByCaseids(caseids));
                    Future<Map<String, Object>> bInspectionFuture = threadPoolTaskExecutor.submit(() -> getCaseInspectionByCaseids(caseids));
                    Future<Map<String, Object>> bCheckFuture = threadPoolTaskExecutor.submit(() -> getCaseCheckByCaseids(caseids));
                    Future<Map<String, Object>> bWpFuture = threadPoolTaskExecutor.submit(() -> getCaseWpByCaseids(caseids));
                    Future<Map<String, Object>> bAttachFuture =null;
                    if (mode == null || mode.indexOf("attach") < 0) {
                        bAttachFuture = threadPoolTaskExecutor.submit(() -> getCaseAttachByCaseids(caseids));
                    }
                    bInfo = bInfoFuture.get();
                    bInfoth=bInfothFuture.get();
                    bInspection=bInspectionFuture.get();
                    bCheck=bCheckFuture.get();
                    bWp=bWpFuture.get();
                    if (mode == null || mode.indexOf("attach") < 0) {
                        if(bAttachFuture!=null){
                            bAttach=bAttachFuture.get();
                        }
                    }
    
                }catch(InterruptedException e){
                    throw e;
    
                }catch (ExecutionException e){
                    throw e;
                }
    

    获取异步返回结果

    当然,使用了submit方法,也就意味着需要得到线程的返回结果,上面返回的future对象中即可取得结果。
    调用future.get()方法会阻塞当前线程,直到相应线程执行完毕返回类型为T的结果。达到同步效果。

    参考

    https://blog.csdn.net/qq_15037231/article/details/80613764

    展开全文
  • 计算1..100 和1...200 的和,使用线程池开启两个线程 调用Executors类的newFixedThreadPool方法参数是线程池容纳的线程数量 这里是2 返回的对象是 ExecutorService类型 用返回的对象 调用submit方法,传入的参数...

    计算1..100  和1...200 的和,使用线程池开启两个线程 

    调用Executors类的newFixedThreadPool方法参数是线程池容纳的线程数量 这里是2 返回的对象是 ExecutorService类型

    用返回的对象 调用submit方法,传入的参数可以是 实现接口类 Runnable  或者是 Callable<数据类型>

    泛型里约束的 数据类型,是Callable实现类的重写方法 call方法的 返回值,通过这个返回值可以将运算的结果 返回输出

    传入的实现类对象,返回值是一个 Featrue类的对象该类的泛型约束的数据类型和 实现类的泛型约束的数据格式一致

    用该类的对象调用get方法即可获得所需要的计算结果返回值。

     

     

    package demo06;
    
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    
    /*
     * 使用多线程技术,求和
     * 两个线程,1个线程计算1..100和,另一个线程计算1..200的和
     * 多线程的异步计算
     */
    public class ThreadPoolDemo {
        public static void main(String[] args) throws InterruptedException, ExecutionException {
            ExecutorService es=Executors.newFixedThreadPool(2);
            Future<Integer> f1=es.submit(new GetSumCallable(100));
            Future<Integer> f2=es.submit(new GetSumCallable(200));
            System.out.println(f1.get());
            System.out.println(f2.get());
            es.shutdown(); //销毁线程池,程序结束。不做这一步,程序将永久保持运行状态,资源得不到释放
        }
    }
    package demo06;
    
    import java.util.concurrent.Callable;
    
    public class GetSumCallable implements Callable<Integer> {
        private int a;
        public GetSumCallable(int a){
            this.a=a;
        }
        public Integer call(){
            int sum=0;
            for(int i=1;i<=a;i++){
                sum+=i;
            }
            
            return sum;
        }
    }

     

    转载于:https://www.cnblogs.com/benjamin77/p/9132768.html

    展开全文
  • 使用qt线程池实现多线程http请求,支持限速下载,可以设置全部下载的网络上限,和单个线程的网络上限。可以实时显示当前下载速度。
  • 线程在进程下进行,一个进程中可以有线程; 继承Thread类重写run方法创建线程 package com.lb; /** * @author LB * @Remarks 继承Thread类重写run方法创建线程 * @date 2020/05/02 14:32 */ public class ...

    1.开启线程

    进程和线程的区别:
    进程是资源调度的最小单位;
    线程是cpu调度的最小单位;
    线程在进程下进行,一个进程中可以有多个线程;

    1.1继承Thread类重写run方法创建线程

    package com.lb;
    
    /**
     * @author LB
     * @Remarks 继承Thread类重写run方法创建线程
     * @date 2020/05/02 14:32
     */
    public class CreateThread extends Thread {
    
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println("i:"+i);
            }
        }
    
        public static void main(String[] args) {
            // 1.创建一个线程
            CreateThread createThread = new CreateThread();
            // 2.开始执行线程 注意 开启线程不是调用run方法,而是start方法
            createThread.start();
    
        }
    }
    
    
    

    1.2实现Runnable接口,重写run方法开启多线程

    package com.lb;
    
    /**
     * @author LB
     * @Remarks 实现Runnable接口,重写run方法开启多线程
     * @date 2020/05/02 14:38
     */
    public class ThreadDemo2 implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println("i:"+i);
            }
        }
    
        public static void main(String[] args) {
            ThreadDemo2 threadDemo2 = new ThreadDemo2();
            Thread thread = new Thread(threadDemo2);
            thread.start();
        }
    }
    
    

    1.3使用匿名内部类方式创建多线程

    package com.lb;
    
    /**
     * @author LB
     * @Remarks 使用匿名内部类方式创建多线程
     * @date 2020/05/02 14:43
     */
    public class ThreadDemo3 {
        public static void main(String[] args) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 10; i++) {
                        System.out.println("i:"+i);
                    }
                }
            });
    
            thread.start();
        }
    }
    
    

    获取线程对象以及名称
    常用线程api方法:

    • start();启动线程
    • currentThread();获取当前线程对象
    • getID();获取当前线程ID
    • getName();获取当前线程名称
    • sleep(long mill) 休眠线程
    • Stop()停止线程;

    什么是守护线程? 守护线程 进程线程(主线程挂了) 守护线程也会被自动销毁
    使用setDaemon(true)方法设置为守护线程

    2.线程池

    线程池是为突然大量爆发的线程设计的,通过有限的几个固定线程为大量的操作服务,减少了创建和销毁线程所需的时间,从而提高效率。
    如果一个线程的时间非常长,就没必要用线程池了(不是不能作长时间操作,而是不宜。),况且我们还不能控制线程池中线程的开始、挂起、和中止。

    2.1可缓存线程池:比较适合任务量大但耗时少的任务

    
    /**
     * @author LB
     * @Remarks 可缓存线程池:比较适合任务量大但耗时少的任务
     * @date 2020/05/02 15:06
     */
    public class NewCachedThreadPoolDemo {
        public static void main(String[] args) {
            ExecutorService newCachedThreadPool  = Executors.newCachedThreadPool();
            for (int i = 0; i < 10; i++) {
                final int temp = i;
                newCachedThreadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(100);
                        } catch (Exception e) {
                            // TODO: handle exception
                        }
                        System.out.println(Thread.currentThread().getName() + ",i:" + temp);
                    }
                });
            }
            //关闭线程池,会继续执行正在执行未完成的任务
            newCachedThreadPool.shutdown();
        }
    }
    

    2.2定长线程池:适用于任务量比较固定但耗时长的任务

    /**
     * @author LB
     * @Remarks 定长线程池:适用于任务量比较固定但耗时长的任务
     * @date 2020/05/02 15:13
     */
    public class NewFixedThreadPoolDemo {
        public static void main(String[] args) {
            ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(5);
            for (int i = 0; i < 10; i++) {
                final int temp = i;
                newFixedThreadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println(Thread.currentThread().getId() + ",i:" + temp);
                    }
                });
            }
        }
    }
    

    2.3可调度线程池:适用于执行定时任务和具体固定周期的重复任务

    /**
     * @author LB
     * @Remarks 可调度线程池:适用于执行定时任务和具体固定周期的重复任务
     * @date 2020/05/02 15:32
     */
    public class NewScheduledThreadPoolDemo {
        public static void main(String[] args) {
            ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(5);
            for (int i = 0; i < 10; i++) {
                final int temp = i;
                newScheduledThreadPool.schedule(new Runnable() {
                    public void run() {
                        System.out.println("i:" + temp);
                    }
                }, 3, TimeUnit.SECONDS);
            }
        }
    }
    

    2.4单线程化的线程池:适用于多个任务顺序执行的场景

    /**
     * @author LB
     * @Remarks 单线程化的线程池:适用于多个任务顺序执行的场景
     * @date 2020/05/02 15:40
     */
    public class newSingleThreadExecutor {
        public static void main(String[] args) {
            ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();
            for (int i = 0; i < 10; i++) {
                final int index = i;
                newSingleThreadExecutor.execute(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println(Thread.currentThread().getName()+",index:"+index);
                        try {
                            Thread.sleep(200);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        }
    }
    

    合理配置线程池:

    操作系统之名称解释:
    某些进程花费了绝大多数时间在计算上,而其他则在等待I/O上花费了大多是时间,
    前者称为计算密集型(CPU密集型)computer-bound,后者称为I/O密集型,I/O-bound。

    CPU密集

    CPU密集的意思是该任务需要大量的运算,而没有阻塞,CPU一直全速运行。
    CPU密集任务只有在真正的多核CPU上才可能得到加速(通过多线程),而在单核CPU上,无论你开几个模拟的多线程,该任务都不可能得到加速,因为CPU总的运算能力就那些。

    IO密集

    IO密集型,即该任务需要大量的IO,即大量的阻塞。在单线程上运行IO密集型的任务会导致浪费大量的CPU运算能力浪费在等待。所以在IO密集型任务中使用多线程可以大大的加速程序运行,即时在单核CPU上,这种加速主要就是利用了被浪费掉的阻塞时间。

    要想合理的配置线程池的大小,首先得分析任务的特性,可以从以下几个角度分析:
    1.任务的性质:CPU密集型任务、IO密集型任务、混合型任务
    2.任务的优先级:高、中、低。
    3.任务的执行时间:长、中、短。
    4.任务的依赖性:是否依赖其他系统资源,如数据库连接等。
    性质不同的任务可以交给不同规模的线程池执行。
    对于不同性质的任务来说,CPU密集型任务应配置尽可能小的线程,如配置CPU个数+1的线程数,IO密集型任务应配置尽可能多的线程,因为IO操作不占用CPU,不要让CPU闲下来,应加大线程数量,如配置两倍CPU个数+1,而对于混合型的任务,如果可以拆分,拆分成IO密集型和CPU密集型分别处理,前提是两者运行的时间是差不多的,如果处理时间相差很大,则没必要拆分了。
    若任务对其他系统资源有依赖,如某个任务依赖数据库的连接返回的结果,这时候等待的时间越长,则CPU空闲的时间越长,那么线程数量应设置得越大,才能更好的利用CPU。
    当然具体合理线程池值大小,需要结合系统实际情况,在大量的尝试下比较才能得出,以上只是前人总结的规律。

    最佳线程数目 = ((线程等待时间+线程CPU时间)/线程CPU时间 )* CPU数目
    比如平均每个线程CPU运行时间为0.5s,而线程等待时间(非CPU运行时间,比如IO)为1.5s,CPU核心数为8,那么根据上面这个公式估算得到:((0.5+1.5)/0.5)8=32。这个公式进一步转化为:
    最佳线程数目 = (线程等待时间与线程CPU时间之比 + 1)
    CPU数目
    可以得出一个结论:
    线程等待时间所占比例越高,需要越多线程。线程CPU时间所占比例越高,需要越少线程。
    以上公式与之前的CPU和IO密集型任务设置线程数基本吻合。

    CPU密集型时,任务可以少配置线程数,大概和机器的cpu核数相当,这样可以使得每个线程都在执行任务
    IO密集型时,大部分线程都阻塞,故需要多配置线程数,2*cpu核数

    展开全文
  • Java 多线程:彻底搞懂线程池

    万次阅读 多人点赞 2019-07-09 19:27:00
    熟悉Java多线程编程的同学都知道,当我们线程创建过多时,容易引发内存溢出,因此我们就有必要使用线程池的技术了。 目录 1 线程池的优势 2 线程池的使用 3 线程池的工作原理 4 线程池的参数 4.1 任务队列...
  • * 线程任务类 */ class MyCallable implements Callable<Map<String, String>> { private String id; public MyCallable(String id) { this.id = id; } @Override public Map<...
  • 线程池多线程处理

    2016-11-04 15:07:01
    线程池多线程处理,如何快速的拿到结果不阻塞 分两种一种按顺序拿取结果一种有结果就返回获取1.public class TestExcel { public static void main(String[] args) throws InterruptedException, ...
  • Java多线程线程池的使用(记录)

    千次阅读 2019-04-16 17:43:49
    可以通过new Thread(runnable).start()开启子线程,但是实际应用中这种开启多线程的方法在线程数非常多的情况下不一定能实现期望的功能,主要是在重复创建和销毁线程时消耗了大量的资源,导致多线程的效率反而没有单...
  • 线程池运行线程

    千次阅读 2019-06-05 15:06:23
    final ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5); for (final MSContact contact : contactList) { fixedThreadPool.execute(new Runnable...
  • java线程池管理多线程的应用

    千次阅读 2018-01-31 17:54:18
    最近有一个需求,前端点击一个按钮,后端需要多线程执行任务,执行完返回结果到前端。使用线程池实现,每次调用新建线程池对象,使用完销毁线程池对象,这个用的是spring线程池,java自带的线程池效果差不多,代码...
  • 这篇文章主要给大家介绍了关于Spring Boot中配置定时任务、线程池多线程池执行的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring Boot具有一定的参考学习价值,需要的朋友们下面来一起学习...
  • public static void main(String[] args) { final ExecutorService newFixedThreadPool2 ... //个任务 newFixedThreadPool2.execute(()->System.out.println("线程一")); newFixedThreadPool2.execute(()->S
  • 多线程,线程通信,线程池和Lambda表达式 1. 多线程 1.1 线程状态 WAITING(无限等待) 当某一个线程被执行wait()方法,需要等待另外的一个线程进行唤醒操作。 一下三个方法都是Object类内的方法: public void wait()...
  • 项目场景:15万条数据需要做逻辑处理,然后存入数据库 硬件:windows 4核 i7 16G内存 问题描述:响应太慢,服务容易出现卡死 ...2.通过多线程执行 多线程配置 新建一个class,把以下配置文件直接原封不动
  • 学习计划 每天学习一小时以上 跟着视频动手编写代码 调试代码并对比课程多提供的源码 课程目标 理解多线程原理并学会c++11 的多线程编程 理解线程池技术原理并能使用c++实现 理解c++11 14 17 20 多线程编程相关特性 ...
  • Java多线程线程池

    万次阅读 2016-05-12 21:28:53
    一、Java自带线程池先看看Java自带线程池的例子,开启5个线程打印字符串List:package com.luo.test;import java.util.ArrayList; import java.util.List; import java.util.concurrent.ArrayBlockingQueue; import ...
  • Python 线程 多线程 线程池

    千次阅读 2018-08-24 13:56:16
    多线程, 线程池测试: Python 使用多线程,有两种方式:函数,或者用类来包装线程对象。 现在有一个需求:如下图,我们需要把test.jpg 复制5000次到update文件夹下面。并且在复制过程中需要重命名,命名规则为 ...
  • 1.@Scheduled定时任务是同步阻塞任务,因为它所使用的线程池是一个单线程线程池,这意味着所有任务都是串行执行,只要前一个任务未执行完成,后面的任务都会一直等待下去,并且当一个任务未执行完成,它的下个触发...
  • 1. 多线程 1.1 WAITING(无限等待) 当某一线程被执行wait()方法,需要等待其他线程进行唤醒操作。 public void wait(); 当前线程进入无线等待状态 开启锁对象 public void notify(); 唤醒一个当前锁对象有关的无线...
  • java线程池创建线程 用Java创建线程 (Creating a thread in Java) To implement multithreading, Java defines two ... 为了实现多线程,Java定义了两种创建线程的方式。 Runnable interface.Runnable接口。 Threa...
  • 使用线程池执行多线程需要如下几个条件 首先是一个线程池线程池包含一些初始化数据,包含队列大小,核心线程数,最大线程数。 然后是一个实现了 runnable的任务,将该任务当如到线程池中进行执行。 线程池...
  • 相对于传统编码的方式使用多线程,在SpringBoot中提供了基于注解的更简单的实现方式: 基于@EnableAsync和@Async注解配置: 项目使用@EnableAsync开启异步,使用@Async 注解在service内的方法上,这样在controller...
  • 而配置线程池可以方便线程的管理,减少线程创建、摧毁带来的性能消耗和提高响应速度等。这篇文章将简单介绍如何配置线程池。 二、什么是CPU核数和逻辑处理器数 ctrl+alt+delete打开任务管理器,打开性能,如下图...
  • Java多线程线程池

    2018-08-05 09:15:32
    一、为什么使用线程池 最基本的开启一个异步任务的方法就是直接像下面这样new一个Thread new Thread(new Runnable() { @Override public void run() { ... 如果并发的线程数量很,并且每个线...
  • 那这个问题,完全就可以用线程池去解决,用线程池维护一定数量的线程,防止无限制的创建线程,带来的内存开销过大。 代码改进: ​ 1. 创建线程池配置类 import org . slf4j . Logger ; import org . slf4...
  • 提高线程的可管理性:线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配、调优和监控 (1)线程池中submit()和exectute()方法的区别? execute():只能...
  • 多线程 1. 线程的声明周期 新建 :从新建一个线程对象到程序start() 这个线程之间的状态,都是新建状态; 就绪 :线程对象调用start()方法后,就处于就绪状态,等到JVM里的线程调度器的调度; 运行 :就绪状态下的...
  • 除了多线程任务执行无序,事实上当前main方法线程和线程池中的多线程任务也会并发执行,修改部分代码: 可以看出,先把main方法中for循环代码执行了(耗时较短,瞬间执行完毕,如果与线程池任务耗时相当,则可看见...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 95,363
精华内容 38,145
关键字:

线程池开启多线程