Java基础练习题 (8)多线程

来源:互联网 发布:2017最新人工智能产品 编辑:程序博客网 时间:2024/05/17 02:51

(1)如何创建并运行一个线程?
有三种方法

  1. 继承 java.lang.Thread 类,重写 run() 方法
public class TestThread extends Thread {  @Override  public void run() {    //do something  }}

调用这个类的 start() 方法就能开始运行线程,当然这里不一定立刻会运行,只是进入就绪状态,注意每个线程只能调用一次 start() 方法。

public static void main(String[] args) {  Thread testThread = new TestThread();  testThread.start();}
  1. 实现 Runnable 接口
public class TestThread implements Runnable {  public void run() {    //do something  }}

将该类传入 Thread 的构造方法作为 target

public static void main(String[] args) {  Thread testThread = new Thread(new TestThread());  testThread.start();}

(2)如何创建和使用Java自带的线程池?

  • 使用 java.util.concurrent.ThreadPoolExecutor 类,这个类有多个构造方法,且参数较多,详情可查阅 API 文档。通常情况下使用 Executors 类来创建线程池。
public class App {  public static void main(String[] args) {    ThreadPoolExecutor threadPool = new ThreadPoolExecutor(10, 20, 10000, TimeUnit.MICROSECONDS, new ArrayBlockingQueue(10));    threadPool.execute(new MyThread());  }}class MyThread implements Runnable {  @Override  public void run() {    //do something  }}
  • 使用 Executors 类的静态方法创建线程池
Executors.newCachedThreadPool(); //创建缓冲线程池Executors.newFixedThreadPool(nThreads);  //创建固定大小线程池Executors.newScheduledThreadPool(corePoolSize);  //创建计划线程池Executors.newSingleThreadExecutor();  //创建单线程池

还有其他线程池的创建方法这里就不在叙述了。查看这些方法的源码可以发现其实是返回一个新建的 ThreadPoolExecutor 类,相当于帮你配置好构造参数。

  • 向线程池提交任务
    execute(Runnable command),还有一个 submit(Runnable task) 方法也可以提交任务,其实内部还是调用的 execute,区别是 submit 方法返回一个 Future。

  • 线程池包含的知识点十分多,这里有很详细的讲解

(3)如何定时运行一个任务?

public class App {  public static void main(String[] args) {    ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(10);    scheduledThreadPool.scheduleWithFixedDelay(new MyThread(), 10, 3, TimeUnit.SECONDS); //执行线程 new MyThread(), 在 10 秒之后, 以 3 秒钟为频率执行  }}class MyThread implements Runnable {  public void run() {    //do something  }}

首先我们先使用 Executors 创建一个 ScheduledThreadPoolExecutor 类,从名字可以看出它可以计划地执行线程。它有两个周期性运行线程地方法

  • scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)

  • scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)

这两个方法的区别是,如果这个线程的执行时间大于 delay/peroid 这个时间,那么当线程执行完成后,前者会等到过了 delay 时间之后再执行线程,而后者会直接执行线程。