java多线程

发布时间 2023-07-22 09:41:02作者: _Explosion!

java中多线程的实现其实和c++类似,介绍几种常用方法

1.继承Thread类,重写其run方法

class MyThread extends Thread{
    public MyThread() {
    }
 
    public MyThread(String name) {
        super(name);
    }
    @Override
    public void run(){
        System.out.println(getName());
    }
}

public class threadTest {
    public static void main(String[] Args){
        Thread test1 = new MyThread("test1");
        Thread test2 = new MyThread("test2");
        Thread test3 = new MyThread("test3");
        test1.run();
        test2.run();
        test3.run();
    }
}

2.实现Runnable接口,实现其run方法

class MyRunnable implements Runnable{
    @Override
    public void run(){
        System.out.println("running");
    }
}

public class threadTest {
    public static void main(String[] Args){
        Thread test1 = new Thread(new MyRunnable());
        Thread test2 = new Thread(new MyRunnable());
        Thread test3 = new Thread(new MyRunnable());
        test1.run();
        test2.run();
        test3.run();
    }
}

3.实现Callable接口(类似于c++中的async任务实现,可获得返回值),重写call方法

FutureTask继承了Future接口并且支持Callable接口注入,从而实现任务式异步。

public class threadTest {
    public static void main(String[] Args){
        //此处用匿名内部类实现Callable接口
        FutureTask<Object> task = new FutureTask(new Callable<String>() {
            @Override
            public String call() throws Exception{
                return new String("mycall");
            }
        });
        Thread th = new Thread(task);
        th.start();
        try{
            //调用get使主线程阻塞至任务结束,获得异步结果
            Object res = task.get();
            System.out.println(res);
        }catch(Exception e){
            e.printStackTrace();
        }

    }
}

线程池

Java中提供了ExecutorService线程池,创建其方法为ThreadPoolExecutor,具体结构如下:

public ThreadPoolExecutor(int corePoolSize,    //核心线程数,创建后不会释放
                              int maximumPoolSize,    //最大线程数(该值需大于等于核心线程数)
                              long keepAliveTime,    //空闲线程最大存活时间
                              TimeUnit unit,    //时间单位TimeUnit
                              BlockingQueue<Runnable> workQueue,    //任务队列
                              ThreadFactory threadFactory,    //线程工厂,用于创建线程
                              RejectedExecutionHandler handler)    //处理阻塞

ExecutorService有如下几个常用方法:

  • execute(Runnable)
  • submit(Runnable)
  • submit(Callable)
  • invokeAny(...)
  • invokeAll(...)

execute接收一个Runnable对象并将其放进任务队列异步执行

submit接收一个Runnable或Callable对象并返回一个Future期约,从而可以检测任务是否完成并获得任务返回值。由上可知,此处也可将FutrueTask对象给予submit

invokeAny和invokeAll接收一个Callable集合,但前者返回集合中随机一个任务的Future,后者返回Future对列,按顺序对应任务集合

 

ExecutorService有两种关闭方式

第一种是shutdown()方法,调用后ExecutorService不再接收任务并等待当前线程池中所有任务结束后关闭。

第二种是shutdownNow()方法,调用后ExecutorService立即关闭。

 

Executors中提供了几种常用线程池:

1.可缓存线程池

创建的线程均为非核心线程,空闲线程存活时间为一分钟。适合生命周期短的任务

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

2.单线程池

只有一个核心线程,使得任务队列满足FIFO

//Executors.newSingleThreadExecutor();
public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

3.固定线程数线程池

固定数量核心线程

//Executors.newFixedThreadPool(n);
public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

4.固定线程数,定时周期线程池

可用于替代handler.postDelay和Timer定时器等延时和周期性任务。

//Executors.newScheduledThreadPool(n);
public ScheduledThreadPoolExecutor(int corePoolSize) {
    super(corePoolSize, Integer.MAX_VALUE,
          DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
          new DelayedWorkQueue());
}

 

同样也可手动创建线程池

private ExecutorService pool = new ThreadPoolExecutor(3, 10,
            10L, TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>(512), Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy());

 

 

 

参考文章:https://blog.csdn.net/fwt336/article/details/81530581