精华内容
下载资源
问答
  • Java多线程

    2021-03-01 06:19:04
    Java多线程之Executor、ExecutorService、Executors、Callable、Future与FutureTask1. 引子初学Java多线程,常使用Thread与Runnable创建、启动线程。如下例:Thread t1 = new Thread(newRunnable() {@Overridepublic ...

    Java多线程之Executor、ExecutorService、Executors、Callable、Future与FutureTask

    1. 引子

    初学Java多线程,常使用Thread与Runnable创建、启动线程。如下例:

    Thread t1 = new Thread(newRunnable() {

    @Overridepublic voidrun() {

    System.out.println(Thread.currentThread().getName());

    }

    });

    t1.start();

    我们需要自己创建、启动Thread对象。

    重要概念:

    实现Runnable的类应该被看作一项任务,而不是一个线程。在Java多线程中我们一定要有一个明确的理解,任务和线程是不同的概念。可以使用线程(Thread)执行任务(比如Runnable),但任务不是线程。

    Java多线程中有两种不同类型的任务,Runnable类型任务(无返回值)与Callable类型任务(有返回值)。

    2. 使用Executor执行线程

    一些已有的执行器可以帮我们管理Thread对象。你无需自己创建与控制Thread对象。比如,你不用在代码中编写new Thread或者thread1.start()也一样可以使用多线程。如下例:

    ExecutorService exec =Executors.newCachedThreadPool();for (int i = 0; i < 5; i++) {//5个任务

    exec.submit(newRunnable() {

    @Overridepublic voidrun() {

    System.out.println(Thread.currentThread().getName()+"doing task");

    }

    });

    }

    exec.shutdown();//关闭线程池

    输出如下:

    pool-1-thread-2doing task

    pool-1-thread-1doing task

    pool-1-thread-3doing task

    pool-1-thread-4doing task

    pool-1-thread-5 doing task

    从输出我们可以看到,exec使用了线程池1中的5个线程做了这几个任务。

    这个例子中exec这个Executor负责管理任务,所谓的任务在这里就是实现了Runnable接口的匿名内部类。至于要使用几个线程,什么时候启动这些线程,是用线程池还是用单个线程来完成这些任务,我们无需操心。完全由exec这个执行器来负责。在这里exec(newCachedThreadPool)指向是一个可以根据需求创建新线程的线程池。

    Executors相当于执行器的工厂类,包含各种常用执行器的工厂方法,可以直接创建常用的执行器。几种常用的执行器如下:

    Executors.newCachedThreadPool,根据需要可以创建新线程的线程池。线程池中曾经创建的线程,在完成某个任务后也许会被用来完成另外一项任务。

    Executors.newFixedThreadPool(int nThreads) ,创建一个可重用固定线程数的线程池。这个线程池里最多包含nThread个线程。

    Executors.newSingleThreadExecutor() ,创建一个使用单个 worker 线程的 Executor。即使任务再多,也只用1个线程完成任务。

    Executors.newSingleThreadScheduledExecutor() ,创建一个单线程执行程序,它可安排在给定延迟后运行命令或者定期执行。

    newSingleThreadExecutor例子如下:

    ExecutorService exec =Executors.newSingleThreadExecutor();for (int i = 0; i < 5; i++) {

    exec.execute(new Runnable() {//execute方法接收Runnable对象,无返回值

    @Overridepublic voidrun() {

    System.out.println(Thread.currentThread().getName());

    }

    });

    }

    exec.shutdown();

    输出如下:

    pool-1-thread-1pool-1-thread-1pool-1-thread-1pool-1-thread-1pool-1-thread-1

    可以看出,虽然有5个任务(5个new Runnable),但是只由1个线程来完成。

    最佳实践:我们应该使用现有Executor或ExecutorService实现类。比如前面说的newCachedThreadPool可以使用线程池帮我们降低开销(创建一个新的线程是有一定代价的),而newFixedThreadPool则可以限制并发线程数。即,我们一般使用Executors的工厂方法来创建我们需要的执行器。

    Executor接口与ExecutorService接口的常用方法

    execute方法:

    Executor接口只有void execute(Runnable command)方法。从方法声明中我们可以看到入参为Runnable类型对象。常用的例子如下:

    Executor executor =anExecutor;

    executor.execute(new RunnableTask1());

    但里面具体怎么执行,是否调用线程执行由相应的Executor接口实现类决定。比如前面的newCachedThreadPool使用线程池来进行执行。Executor将任务提交与每个任务如何运行(如何使用线程、调度)相分离。

    submit方法:

    ExecutorService接口继承自Executor接口,扩展了父接口中的execute方法。有两个常用的submit方法

    Future>submit(Runnable task) Future submit(Callable task)

    可以看到这两个常用方法一个接收Runnable类型入参,一个接收Callable类型入参。Callable入参允许任务返回值,而Runnable无返回值。也就是说如果我们希望线程有一个返回结果,我们应该使用Callable类型入参。

    invokeAll与invokeAny方法:

    批量执行一组Callable任务。其中invokeAll是等所有任务完成后返回代表结果的Future列表。而invokeAny是等这一批任务中的任何一个任务完成后就返回。从两个方法的返回结果我们也可以看出两个方法的不同:

    List> invokeAll(Collection extends Callable>tasks) T invokeAny(Collection extends Callable> tasks)

    invokeAll返回的是List,而invoke返回的是T。

    shutdown()方法:

    启动一次顺序关闭,执行以前提交的任务,但不接受新任务。执行此方法后,线程池等待任务结束后就关闭,同时不再接收新的任务。如果执行完shutdown()方法后,再去执行execute方法则直接抛出RejectedExecutionException。不要问我为什么知道...刚从坑里爬出来。

    原则:只要ExecutorService(线程池)不再使用,就应该关闭,以回收资源。要注意这个不再使用。

    上述方法较多,可以配合后面的实例进行理解。可以先记住execute方法与shutdown方法。

    3. 使用Callable与Future

    Callable接口

    Runnable接口中的public void run()方法无返回值,如果我们希望线程运算后将结果返回,使用Runnable就无能为力。这时候我们应使用Callable。Callable代表有返回值的任务。一个实现Callable接口的类如下所示:

    class CalcTask implements Callable{

    @OverridepublicString call() throws Exception {returnThread.currentThread().getName();

    }

    }

    这个任务比较简单,就是返回当前线程的名字。与Runnable相比较有一个返回值,在这里返回值类型为String,也可以为其他类型。

    使用如下代码进行调用:

    ExecutorService exec =Executors.newCachedThreadPool();

    List> taskList = new ArrayList>();/*往任务列表中添加5个任务*/

    for (int i = 0; i < 5; i++) {

    taskList.add(newCalcTask());

    }/*结果列表:存放任务完成返回的值*/List> resultList = new ArrayList>();try{/*invokeAll批量运行所有任务, submit提交单个任务*/resultList=exec.invokeAll(taskList);

    }catch(InterruptedException e) {

    e.printStackTrace();

    }try{/*从future中输出每个任务的返回值*/

    for (Futurefuture : resultList) {

    System.out.println(future.get());//get方法会阻塞直到结果返回

    }

    }catch(InterruptedException e) {

    e.printStackTrace();

    }catch(ExecutionException e) {

    e.printStackTrace();

    }

    输出如下:

    pool-1-thread-1pool-1-thread-2pool-1-thread-3pool-1-thread-4pool-1-thread-5

    Future接口

    上面的例子中我们使用了Future接口。Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。上面的例子中exec执行器执行了一个Callable类型的任务列表然后得到了Futuer类型的结果列表resultList。

    get方法

    等待计算完成,然后获取其结果。

    isDone方法

    用来查询任务是否做完,例子如下:

    /*新建一个Callable任务*/Callable callableTask = new Callable() {

    @OverridepublicInteger call() throws Exception {

    System.out.println("Calculating 1+1!");

    TimeUnit.SECONDS.sleep(2);//休眠2秒

    return 2;

    }

    };

    ExecutorService executor=Executors.newCachedThreadPool();

    Future result =executor.submit(callableTask);

    executor.shutdown();while(!result.isDone()){//isDone()方法可以查询子线程是否做完

    System.out.println("子线程正在执行");

    TimeUnit.SECONDS.sleep(1);//休眠1秒

    }try{

    System.out.println("子线程执行结果:"+result.get());

    }catch (InterruptedException |ExecutionException e) {

    e.printStackTrace();

    }

    输出如下:

    Calculating 1+1!子线程正在执行

    子线程正在执行

    子线程执行结果:2

    4. FutureTask

    FutureTask类是 Future 接口的一个实现。FutureTask类实现了RunnableFuture接口,RunnableFuture继承了Runnable接口和Future接口,所以:

    FutureTask可以作为Runnable被线程执行

    可以作为Future得到传入的Callable对象的返回值

    例子如下:

    FutureTask futureTask = new FutureTask<>(new Callable() {

    @OverridepublicInteger call() throws Exception {

    System.out.println("futureTask is wokring 1+1!");return 2;

    }

    });

    Thread t1= new Thread(futureTask);//1.可以作为Runnable类型对象使用

    t1.start();try{

    System.out.println(futureTask.get());//2.可以作为Future类型对象得到线程运算返回值

    } catch(ExecutionException e) {

    e.printStackTrace();

    }

    输出如下:

    futureTask is wokring 1+1!

    2

    可以看出FutureTask可以当作一个有返回值的Runnable任务来用。

    分析:FutureTask futureTask = new FutureTask<>(new Callable...)相当于把Callable任务转换为Runnable任务,就可以使用线程来执行该任务。而futureTask.get()相当于将Callable转化为Future,从而得到异步运算的结果。

    ExecutorService执行器除了接收Runnable与Callable类型的入参,也可以接收FutureTask类型,例子如下:

    FutureTask futureTask = new FutureTask<>(new Callable() {

    @OverridepublicInteger call() throws Exception {

    System.out.println("futureTask is wokring 1+1!");

    TimeUnit.SECONDS.sleep(2);return 2;

    }

    });

    ExecutorService executor=Executors.newCachedThreadPool();

    executor.submit(futureTask);//也可以使用execute,证明其是一个Runnable类型对象

    executor.shutdown();while(!futureTask.isDone()){

    System.out.println("子线程还没做完,我再睡会");

    TimeUnit.SECONDS.sleep(1);

    }try{

    System.out.println("子线程运行的结果:"+futureTask.get());

    }catch (InterruptedException |ExecutionException e) {

    e.printStackTrace();

    }

    参考资料

    展开全文
  • 且UI的 更新只能在主线程中完成,异步处理是不可避免的AsyncTask的特点是由系统来创建和删除执行任务的线程,并有效的管理它们开发者只要创建AsyncTask的子类,实现相应的方法。再创建AsyncTask子类的对象,并执行...

    Handler使用比较复杂

    Handler和AsyncTask都是为了不阻塞主线程,且UI的 更新只能在主线程中完成,异步处理是不可避免的

    AsyncTask的特点是由系统来创建和删除执行任务的线程,并有效的管理它们

    开发者只要创建AsyncTask的子类,实现相应的方法。再创建AsyncTask子类的对象,并执行execute()方法就可以 了

    class MyTask extends AsyncTask {

    /**

    运行在后台,相当于是Thread 中run方法

    *运行在子线程中的方法

    */

    @Override

    protected Void doInBackground (Void. .. params) {

    for(int i=0;i<=100;i++) {

    publishProgress (i) ;

    try {

    Thread. sleep (1000) ;

    } catch (InterruptedException e) {

    e . printstackTrace () ;

    }

    }

    return nu11 ;

    }

    /**

    *进度指示的方法

    *运行在主线程中,在这个方法中可以直接更新控件的属性

    */

    @Override

    protected void onProgressUpdate (Integer... values) {

    int num =values [0] ;

    tvTest . setText ("num: "+num) ;

    super . onProgressUpdate (values) ;

    }

    /**

    *运行在主线程中,当后台运行结束,自动调用的方法

    */

    @Override

    protected void onPostExecute (Void result) {

    Toast . makeText (MainActivity. this, "子线程运行结束",Toast. LENGTH LONG) .show() ;

    super . onPostExecute (result) ;

    }

    执行:

    new MyTask() . execute () ;

    读取文件示例:

    class ReadFileTask extends AsyncTask {

    @Override

    protected String doInBackground (File. . . params) {

    return read (params [0]) ;

    }

    @Override

    protected void onPostExecute (String result) {

    etContent. setText (result) ;

    super . onPostExecute (result) ;

    }

    private String read(File file) {

    stringBuilder sb=new StringBuilder() ;

    BufferedReader bre nul1 ;

    try {

    br =new BufferedReader (new InputstreamReader (new FileInputstream (file)) )

    String line =br . readLine () ;

    while (line!=nu1l) {

    sb . append (line+"\n") ;

    line = br. readLine() ;

    }

    return sb.toString();

    } catch (FileNotFoundException e) {

    e.printstackTrace() ;

    } catch(IOException e){

    e.printstackTrace () ;

    }finally{

    try {

    if (br!=null) {

    br.close() ;

    } catch (IOException e) {

    e. printstackTrace () ;

    }

    return null;

    }

    执行:

    btnRead . setonClickListener (new View . OnClickListener () {

    @Override

    public void onClick (View v) {

    //执行子线程,完成读取文件工作

    File file=new File (Environment. getExternalStorageDirectory() , "test. txt") ;

    new ReadFileTask () . execute (file) ;

    }

    }) ;

    本文地址:https://blog.csdn.net/qq_43496675/article/details/107904983

    如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

    展开全文
  • 在Java5之后,并发线程这块发生了根本的变化,最重要的莫过于新的启动、调度、管理线程的一大堆API了。在Java5以后,通过 Executor来启动线程比用Thread的...创建的时候实run方法即可。二、执行任务通过java.util.c...

    在Java5之后,并发线程这块发生了根本的变化,最重要的莫过于新的启动、调度、管理线程的一大堆API了。在Java5以后,通过 Executor来启动线程比用Thread的start()更好。在新特征中,可以很容易控制线程的启动、执行和关闭过程,还可以很容易使用线程池的特 性。

    一、创建任务

    任务就是一个实现了Runnable接口的类。

    创建的时候实run方法即可。

    二、执行任务

    通过java.util.concurrent.ExecutorService接口对象来执行任务,该接口对象通过工具类java.util.concurrent.Executors的静态方法来创建。

    Executors此包中所定义的 Executor、ExecutorService、ScheduledExecutorService、ThreadFactory 和 Callable 类的工厂和实用方法。

    ExecutorService提供了管理终止的方法,以及可为跟踪一个或多个异步任务执行状况而生成 Future 的方法。 可以关闭 ExecutorService,这将导致其停止接受新任务。关闭后,执行程序将最后终止,这时没有任务在执行,也没有任务在等待执行,并且无法提交新任 务。

    executorService.execute(new TestRunnable());

    1、创建ExecutorService

    通过工具类java.util.concurrent.Executors的静态方法来创建。

    Executors此包中所定义的 Executor、ExecutorService、ScheduledExecutorService、ThreadFactory 和 Callable 类的工厂和实用方法。

    比如,创建一个ExecutorService的实例,ExecutorService实际上是一个线程池的管理工具:

    ExecutorService executorService = Executors.newCachedThreadPool();

    ExecutorService executorService = Executors.newFixedThreadPool(3);

    ExecutorService executorService = Executors.newSingleThreadExecutor();

    2、将任务添加到线程去执行

    当将一个任务添加到线程池中的时候,线程池会为每个任务创建一个线程,该线程会在之后的某个时刻自动执行。

    示例1:

    @Test

    public void testDemo() throws Exception {

    //单例线程,任意时间(同一时间)池中只能有一个线程

    ExecutorService es = Executors.newSingleThreadExecutor();

    es.execute(new Runnable() {

    @Override

    public void run() {

    System.err.println("线程启动并运行"+Thread.currentThread().getName());

    }

    });

    es.execute(new Runnable() {

    @Override

    public void run() {

    System.err.println("第二个也运行了"+Thread.currentThread().getName());

    }

    });

    //Thread.sleep(1000 * 60 * 60);

    }

    运行结果如下:两个都会执行,但程序只会使用一个线程来运行。

    线程启动并运行pool-1-thread-1

    第二个也运行了pool-1-thread-1

    示例2:

    @Test

    public void testDemo3() throws Exception {

    //声明一个线程池

    ExecutorService ex = Executors.newCachedThreadPool();

    for (int i = 0; i < 4; i++) {

    final int a = i;

    //每一次execute方法,都是向池中放入一个对象

    ex.execute(new Runnable() {

    public void run() {

    while(true){

    System.err.println("测试...."+a+">"

    +Thread.currentThread().getName()+","

    +Thread.currentThread().isDaemon());

    try{

    Thread.sleep(2000);

    }catch(Exception e){

    e.printStackTrace();

    }

    }

    }

    });

    }

    Thread.sleep(1000*60*60);

    } 输出的结果如下:从中可以发现,第四个一组输出,即一共创建了四个线程,每次每个线程都会执行输出,但不按顺序:位每一次输出都四个算是一组

    测试....0>pool-1-thread-1,false

    测试....3>pool-1-thread-4,false

    测试....2>pool-1-thread-3,false

    测试....1>pool-1-thread-2,false

    测试....0>pool-1-thread-1,false

    测试....3>pool-1-thread-4,false

    测试....2>pool-1-thread-3,false

    测试....1>pool-1-thread-2,false

    测试....1>pool-1-thread-2,false

    测试....2>pool-1-thread-3,false

    测试....3>pool-1-thread-4,false

    测试....0>pool-1-thread-1,false

    示例3:

    public void testCall() throws Exception{

    //声明一个类,可以被调用,类似于线程,但它可以拥有返回值

    class MyCall implements Callable{

    private int seq;

    public MyCall(int seq){

    this.seq=seq;

    }

    //抛出异常并可以拥有返回值

    public String call() throws Exception {

    System.err.println("执行"+seq+","+Thread.currentThread().getName());

    Thread.sleep(3000);

    System.err.println("Weak up "+seq);

    return "完成"+seq;//这是返回值

    }

    }

    ExecutorService es = Executors.newCachedThreadPool();//创建线程池对象

    List> result =new ArrayList>();//放结果用的集合

    for(int i=0;i<3;i++){

    Future f=es.submit(new MyCall(i));//线程执行完成以后可以通过引用获取返回值

    result.add(f);

    }

    for(Future f:result){

    System.err.println("返回值:"+f.get());//输出返回的值

    }

    System.err.println("完成....");

    }

    展开全文
  • 通过对个任务重用线程线程创建的开销被分摊到个任务上。其好处是,因为在请求到达时线程已经存在,所以无意中也消除了线程创建所带来的延迟。这样就可以立即为请求服务,使应用程序响应更快。而且,通过适当地...

    6、使用线程池ExecuteService

    线程池为线程生命周期开销问题和资源不足问题提供了解决方案。通过对多个任务重用线程,线程创建的开销被分摊到多个任务上。其好处是,因为在请求到达时线程已经存在,所以无意中也消除了线程创建所带来的延迟。这样就可以立即为请求服务,使应用程序响应更快。而且,通过适当地调整线程池中的线程数目,也就是当请求的数目超过某个阈值时,就可以强制其他任何新到的请求一直等待,直到获得一个线程来处理位置,从而防止资源不足。

    线程池是管理线程的高级技术,通常它提供了如下几个功能通过对线程的管理,更加合理的调配资源。通常,线程池里维护着一组空闲线程,并向外提供,根据系统繁忙程度动态增加或减少空闲线程的数量。比较高级的还提供了自动检测异常的功能。

    通过维护线程池中的既存线程,可以节省创建线程的开销,尤其是对WebServer这类处理频繁,而处理过程又比较快的程序,创建线程的开销不能忽略。

    java.util.concurrent提供了互斥、信号量、诸如在并发访问下执行得很好的队列和散列表之类的集合类及几个工作队列实现。该包中的Excutors类是一种有效的、广泛使用的以工作队列为基础的线程池的正确实现。个人无须尝试编写自己的线程池,容易出错。

    线程池的创建很简单,只需要使用Excutors.newFixedThreadPool(i)函数即可创建大小为i的线程池,实例属于ExecutorService类型。然后可以调用该类的execute()函数来启动一个线程,输入的参数为线程的变量。

    下面是一个简单的例子,使用了2个大小的线程池来处理100个线程。

    注意:线程池必须使用shutdown来显示关闭,否则主线程无法退出。

    shutdown不会阻塞主线程

    package org.test.thread;

    import java.util.concurrent.ExecutorService;

    import java.util.concurrent.Executors;

    /**

    * @author Administrator

    *

    *使用两个线程池来处理100个线程

    *

    */

    public class TestExecuteService {

    public static void main(String[] args) {

    ExecutorService exec = Executors.newFixedThreadPool(2);

    for(int i = 0;i 

    //定义一个内部类

    Runnable run = new Runnable() {

    @Override

    public void run() {

    // TODO Auto-generated method stub

    long time = (long) (Math.random() * 1000);

    System.out.println("休眠"+time);

    try {

    Thread.sleep(time);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    };

    exec.execute(run);

    }

    //必须关闭线程池

    exec.shutdown();

    }

    }

    在循环过程中,对等待线程池中有空闲的线程,所以主线程会阻塞,为了解决这个问题,一般启动一个线程来做for循环,就是为了避免由于线程池满了造成主线程阻塞。代码如下所示:package org.test.thread;

    import java.util.concurrent.ExecutorService;

    import java.util.concurrent.Executors;

    /**

    * @author Administrator

    *

    *使用两个线程池来处理100个线程

    */

    public class TestExecuteService {

    public static void main(String[] args) {

    new TestExecuteService().testExec(2,100);

    new TestExecuteService().testForExec(2,100);

    }

    /**

    * 可能会出现线程阻塞

    * */

    private void testExec(int poolSize,int threadSize) {

    ExecutorService exec = Executors.newFixedThreadPool(poolSize);

    for(int i = 0;i 

    //定义一个内部类

    Runnable run = new Runnable() {

    @Override

    public void run() {

    // TODO Auto-generated method stub

    long time = (long) (Math.random() * 1000);

    System.out.println("休眠"+time);

    try {

    Thread.sleep(time);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    };

    exec.execute(run);

    }

    //必须关闭线程池

    exec.shutdown();

    }

    /**

    * 用一个线程来处理for循环

    * */

    private void testForExec(final int poolSize,final int threadSize){

    //创建内部类

    class Test extends Thread{

    @Override

    public void run() {

    ExecutorService exec = Executors.newFixedThreadPool(poolSize);

    for (int i = 0; i 

    //定义一个内部类

    Runnable run = new Runnable() {

    @Override

    public void run() {

    // TODO Auto-generated method stub

    long time = (long) (Math.random() * 1000);

    System.out.println("休眠 "+time);

    try {

    Thread.sleep(time);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    };

    exec.execute(run);

    }

    //必须显示关闭线程池

    exec.shutdown();

    }

    }

    new Test().start();

    }

    }

    在我们编写基于Socket的服务器程序时,通常的做法是,每连接一个客户端都为它创建一个新的线程,客户端离开后再销毁该线程。但是如果频繁的创建多个线程并销毁,对系统资源会造成很大的浪费。然而使用线程池技术就可以大大减少程序的创建和销毁次数,提高服务器的工作效率。

    展开全文
  • 查看ThreadPoolExecutor源码,在该类中定义了一个内部类Worker,ThreadPoolExecutor线程池中的工作线程就是Worker类的实例,Worker实例在执行时会调用beforeExecute()与afterExecute()方法 package com.Executor; ...
  • 多线程中execute 和submit区别 一,execute方法 public interface Executor { /** * Executes the given command at some time in the future. The command * may execute in a new thread, in a pooled thread, ...
  • 本人近来需要在servlet里另起线程池,以便控制,因为servlet的线程是不为我们能控制的,所以无奈之下,使用了ThreadPoolExecutor类。 但是有些任务需要在自己创建的线程池里执行完了,servlet的程序才继续执行。 ...
  • 喜欢的话麻烦点下Star哈文章首发于我的个人weixin :c3207130476Java中的线程Java之父对线程的定义是:线程是一个独立执行的调用序列,同一个进程的线程在同一时刻共享一些系统资源(比如文件句柄等)也能访问同一个...
  • 多线程调用static方法线程安全问题

    千次阅读 2021-11-10 15:44:42
    最近在工作中遇到了线程安全的问题,是在一个方法中调用了静态方法解析Date的字符串。 因为 SimpleDateFormat这个类是线程不安全的,所以不能在静态方法中定义全局的成员变量。 @Test void contextLoads() { ...
  • 我有以下三种方法的课程public class MyRunnable implements Runnable {@Overridepublic void run() {// what code need to write here//to call the specific methods based on request types}public int add(int a...
  • 这里将多线程三种实现方法:1.继承Thread类。2.实现runnable方法。3.线程池。 先说第一种:继承Thread类 为了便于理解,我们假设这样一个场景:我有两只猫,我要给他们同时喂食。 这是猫的类,这个类继承了Thread...
  • Java 多线程传值的四种方法作者: sunjs 更新时间:2020-09-11 15:20:16 原文链接其实大家都知道多线程传值有三种方式:1:通过构造方法传递数据2:通过变量和方法传递数据3:通过回调函数传递数据那么博主有个非常...
  • 线程池有有两种提交任务的方法一种是execute由根接口Executor提供,第二种是ExecutorService提供的submit方法 该方法有三种重载方法,我们完全可以拿submit方法替代execute方法;本质上这四种方法最后都殊途同归都是...
  • ThreadPoolExecutor的execute方法执行流程 前言 【Java线程池01】Java线程池简介 此文中对Java线程池简介,包含线程池相关的几个类的关系等。 【Java线程池02】ThreadPoolExecutor类概述 此文介绍了...
  • 1. 多线程技术 1.1 线程与进程 进程 ​ 是指一个内存中运行的应用程序(现在很多软件都是多进程的了,比如百度云),是系统运行程序的基本单位,每个进程都有一个独立(进程之间的内存不共享)的内存空间 。 ​ ...
  • 如果线程同时访问同一个静态方法,后一个线程传递的参数值会覆盖前一个线程传递的参数值吗?代码示例如下:被访问的静态资源:public class C {public static void test(String[] value) throws ...
  • 详细内容本篇文章给大家带来的内容是关于Java多线程批量数据导入的方法介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。前言:当遇到大量数据导入时,为了提高处理的速度,可以选择使用多线程...
  • 因此,开多线程来执行批量任务是十分重要的一种批量操作思路,其实这种思路实现起来也十分简单,就拿批量更新的操作举例:整体流程图步骤 获取需要进行批量更新的大集合A,对大集合进行拆分操作,分成N个小集合A-1 ~...
  • 多线程下实现数组的读与写,用到的是Java的copyOnWriteArrayList数组,具体其有关的解释,可看往期的 package com.lcz.thread; import java.util.Random; import java.util.concurrent.ArrayBlockingQueue; import ...
  • 本文实例讲述了Python基于多线程实现抓取数据存入数据库的方法。分享给大家供大家参考,具体如下:1. 数据库类 """使用须知:代码中数据表名 aces ,需要更改该数据表名称的注意更改"""import pymysqlclass Database...
  • java.util.concurrent包里提供了关于多线程操作的类,平常用的比较多的是ExecutorService及其实现类(如... ExecutorService(继承自Executor)接口:提供了一些异步的多线程操作方法,如execute(), submit(), shutdo...
  • 实现 Runnable 接口3.Callable和Future实现有返回结果的多线程基于线程池的方式二、4种线程池1.newCachedThreadPool2.newFixedThreadPool3.newScheduledThreadPool4.newSingleThreadExecutor三、线程生命周期(状态)...
  • 多线程是java语言区别于其它...在java5以前实现多线程有两种方法(继承Thread类和实现Runnable接口)它们分别为:使用new Thread()和new Thread(Runnable)形式第一种直接调用thread的run方法,所以,我们往往使用Th...
  • 1.JAVA多线程实现方式JAVA多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带...
  • //So that other thread also get the chance to execute. } catch (Exception ex) { ex.printStackTrace(); } } } }; Thread thread2 = new Thread() { public void run() { while (linuxCmd) { try { ...
  • 继承Thread类创建线程Thread类本质上是实现了Runnable接口的一个实例,代表一个...这种方式实现多线程很简单,通过自己的类直接extend Thread,并复写run()方法,就可以启动新线程并执行自己定义的run()方法。例如...
  • 对于所有语言来说,多线程的编程是绝不可少的。同样的Java语言也包含了多线程的开发。首先,我们先来了解一下Java语言的多线程实现方式。一、Java 多线程实现方式java中实现多线程的方式有三种,接下来我将会逐个...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 181,380
精华内容 72,552
关键字:

多线程execute方法