创建线程方法一
创建一个类去继承Thread
类
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
接口只有一个方法,并且是一个函数式接口
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
创建完类之后,我们不能直接创建MyThread
对象进行调用run()
而是,调用Thread
类里的start()
方法
new MyThread().start();
这样,我们就开启了一个线程,并且执行线程中的方法
创建线程方法二
第二种是接口 Runnable
自己创建一个类 去实现Runnable
接口,重新run
方法
public class MyThread extends Runnable {
@Override
public void run(){
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName()+":"+"这里是子线程");
}
}
}
new Thread(new MyThread).start();// 通过这种方法是去调用线程启动
这里其实是需要一个Runnable
子类去实现它的方法,因此,我们可以使用匿名内部类或者 jdk1.8 Lambda
表达式
public class Test{
public static void main(String[] args) {
Runnable r = ()->{
// 这里是我们需要重新run方法的实际内容
}
new Thread(r).start();// 通过这种方法是去调用线程启动
}
}
创建线程方法三
实现 callable 的接口
创建线程方法四(线程池)
newCachedThreadPool
根据我们的任务数量,创建线程
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
使用Executors
来创建各种各样的线程池
其中,要让线程池中的线程执行任务,则调用 execute() 方法和 submit()方法
execute()
和submit()
的区别
传入类型不同
void execute(Runnable command);
只接受实现了 Runnable
接口的类
而submit()
可以有三种重载形式
<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
这种线程池可以指定线程的数量
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
其中执行线程的方法与上面的一样,可参考上面的代码
newScheduledThreadPool
根据名称可得这个是个可以延迟时间来执行线程任务的线程池
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(10);
这里的返回值,不要用父类 ExecutorService
因为父类里面没有 ScheduledExecutorService
里的延迟方法,
Runnable runnable = ()->{
System.out.println("1111");
};
scheduledThreadPool.schedule(runnable,5,TimeUnit.SECONDS);
第二个参数是延迟的时间,第三个参数是延迟时间的单位
newSingleThreadExecutor()
单线程执行池