Skip to content

创建线程方法一

创建一个类去继承Thread

java
public class MyThread extends Thread {
    @Override
    public void run(){
        for (int i = 0; i < 20; i++) {
            System.out.println(Thread.currentThread().getName()+":"+"这里是子线程");
        }
    }
}

其中,Thread 类实现了 Runnable 接口

Runnable 接口只有一个方法,并且是一个函数式接口

java
@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

创建完类之后,我们不能直接创建MyThread 对象进行调用run()

而是,调用Thread 类里的start() 方法

java
new MyThread().start();

这样,我们就开启了一个线程,并且执行线程中的方法

创建线程方法二

第二种是接口 Runnable

自己创建一个类 去实现Runnable 接口,重新run 方法

java
public class MyThread extends Runnable  {
    @Override
    public void run(){
        for (int i = 0; i < 20; i++) {
            System.out.println(Thread.currentThread().getName()+":"+"这里是子线程");
        }
    }
}
java
new Thread(new MyThread).start();// 通过这种方法是去调用线程启动

这里其实是需要一个Runnable 子类去实现它的方法,因此,我们可以使用匿名内部类或者 jdk1.8 Lambda 表达式

java
public class Test{
    public static void main(String[] args) {
    	Runnable  r = ()->{
            // 这里是我们需要重新run方法的实际内容
        }
        new Thread(r).start();// 通过这种方法是去调用线程启动
    }
}

创建线程方法三

实现 callable 的接口

创建线程方法四(线程池)

newCachedThreadPool

根据我们的任务数量,创建线程

java
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

使用Executors 来创建各种各样的线程池

其中,要让线程池中的线程执行任务,则调用 execute() 方法和 submit()方法

execute()submit() 的区别

传入类型不同

java
void execute(Runnable command);

只接受实现了 Runnable 接口的类

submit() 可以有三种重载形式

java
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);

返回值

execute() 没有返回值

submit(Callable<T> task); 有返回值 返回对象 Future

如果我们需要获取返回值 则调用Future 中的 get()方法

submit(Runnable task); 没有返回值,就算使用Future 中的get()方法也只会返回 null

submit(Runnable task, T result); 这种 会返回 result 的值

细节方面,execute()可以抛出异常和正常处理

submit() 只要不调用获取返回值,都会吃掉异常

newFixedThreadPool

这种线程池可以指定线程的数量

java
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);

其中执行线程的方法与上面的一样,可参考上面的代码

newScheduledThreadPool

根据名称可得这个是个可以延迟时间来执行线程任务的线程池

java
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(10);

这里的返回值,不要用父类 ExecutorService 因为父类里面没有 ScheduledExecutorService 里的延迟方法,

java
Runnable runnable = ()->{
            System.out.println("1111");
        };
scheduledThreadPool.schedule(runnable,5,TimeUnit.SECONDS);

第二个参数是延迟的时间,第三个参数是延迟时间的单位

newSingleThreadExecutor()

单线程执行池