Java 多线程:创建线程的四种方式
Posted PS-Jerry
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 多线程:创建线程的四种方式相关的知识,希望对你有一定的参考价值。
创建线程的四种方式
方式一:继承自Thread 类
方法步骤
- 1.创建一个继承于Thread类的子类
- 2.重写Thread 类的 run()方法-> 将线程的执行操作声明到run()中
- 3.创建Thread 类的子类对象
- 4.通过此对象调用start() 方法
例如: 输出0~100 以内所有的偶数
public class ThreadInheritTest {
public static void main(String[] args) {
//3.new 一个继承自Thread类的对象
MyInheritThread myThread = new MyInheritThread();
//4.启动线程
myThread.start();
}
}
//1.创建一个继承自Thread 的子类
class MyInheritThread extends Thread {
//2.重写父类中Thread 的run方法
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if (i % 2 == 0) {
System.out.println(Thread.currentThread().getName() + ": " + i);
}
}
}
}
注意:我们不能通过run方法启动线程,而是应该通过start方法启动线程。
方式二:实现Runnable 接口
方法步骤
- 1.创建一个实现Runnable接口的类。
- 2.重写Runnable 类的 run()方法-> 将线程的执行操作声明到run()中
- 3.创建实现当前Runnable 接口类的对象。
- 4.将上述对象作为参数传入到Thread 类的构造器中。
- 5.通过Thread类的对象调用start() 方法启动线程。
例如:输出1~100 以内所有的偶数
public class ThreadRunnableTest {
public static void main(String[] args) {
MyRunnableThread myRunnableThread = new MyRunnableThread();
Thread t1 = new Thread(myRunnableThread);
t1.start();
}
}
class MyRunnableThread implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if (i % 2 == 0) {
System.out.println(Thread.currentThread().getName() + ": " + i);
}
}
}
}
方式三:实现Callable 接口
实现Callable 接口,该接口是JDK 5.0 中新增的。
步骤
- 1.创建一个实现
Callable
的实现类 - 2.实现
call()
方法,将此线程需要执行的操作声明到call()
方法中,注意该方法是有返回值的。 - 3.创建
Callable
接口实现类的对象 - 4.将此
Callable
实现类的对象(numThread)传递FutureTask
构造其中,创建FutureTask
对象。 - 5.将
FutureTask
创建的对象,传递到Thread
构造器中,在start
该线程。 - 6.如果关心线程中
call()
方法的返回值,则可以用个futureTask.get()
来抓取返回值。
例如:如下代码用于计算0~100以内,所有偶数的和
package com.jerry.thread10;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class ThreadCallableTest {
public static void main(String[] args) {
//3.创建Callable接口实现类的对象
NumThread numThread = new NumThread();
//4.将此Callable实现类的对象(numThread)传递FutureTask构造其中,创建FutureTask对象。
FutureTask<Integer> futureTask = new FutureTask<Integer>(numThread);
//5.将FutureTask创建的对象,传递到Thread构造器中,在start该线程。
new Thread(futureTask).start();
//6.如果关心线程中call方法的返回值,则可以用个futureTask.get() 来抓取返回值。
try {
//拿到其返回值
Integer sum = futureTask.get();
System.out.println("总和为: " + sum);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
//1.创建一个实现Callable 的实现类
class NumThread implements Callable<Integer> {
//2.实现call方法,将此线程需要执行的操作声明到call方法中,注意该方法是有返回值的。
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i <= 100; i++) {
if (i % 2 == 0) {
System.out.println(i);
sum += i;
}
}
return sum;
}
}
注意: 如何理解Callable 接口更强大?
- call() 方法是有返回值得。
- call() 可以抛出异常,被外面的操作捕获,获取异常信息。
- Callable 中是支持泛型的,这个泛型就是用futureTask.get()的返回值。
方式四:使用线程池(ThreadPool)
1、使用线程池的好处
- 1.提高了响应速度(减少了创建线程的时间)
- 2.降低资源消耗(重复利用线程池中的线程,不需要每次都创建)
- 3.便于管理,如可设置如下属性管理线程池
-
corePoolSize
线程池大小
-
maximumPoolSize
最大线程数
-
keepAliveTime
线程没有任务时,最多保持多长时间后会终止
-
2、步骤
这里我们只演示了通过Runnable 实现接口方式构建run方法
- 1.创建一个固定大小的线程池
- 2.设置线程池属性
- 3.使用
execute
执行当前线程,excute
适合用于Runnable
方式,当线程方法是Callable
时要用submit
- 4.使用
shutdown
方法关闭当前线程,线程池不用了,则关闭当前线程。
例如:如下代码创建了固定可容纳10个线程的线程池,当中有两个线程,分别输出奇数和偶数
package com.jerry.thread10;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
public class ThreadPoolTest {
public static void main(String[] args) {
//1.创建一个固定大小的线程池
ExecutorService service = Executors.newFixedThreadPool(10);
//2.设置线程池属性
ThreadPoolExecutor executor1 = (ThreadPoolExecutor) service;
executor1.setCorePoolSize(10);
//3.执行当前线程,适合用于Runnable,Callable 要用submit
service.execute(new NumThread1());//执行线程1,用于输出偶数
service.execute(new NumThread2());//执行线程2,用于输出奇数
//4.关闭当前线程,线程池不用了,则关闭当前线程
service.shutdown();
}
}
class NumThread1 implements Runnable {
//输出偶数
@Override
public void run() {
for (int i = 0; i <= 100; i++) {
if (i % 2 == 0) {
System.out.println(Thread.currentThread().getName() + ": " + i);
}
}
}
}
class NumThread2 implements Runnable {
//输出奇数
@Override
public void run() {
for (int i = 0; i <= 100; i++) {
if (i % 2 != 0) {
System.out.println(Thread.currentThread().getName() + ": " + i);
}
}
}
}
以上是关于Java 多线程:创建线程的四种方式的主要内容,如果未能解决你的问题,请参考以下文章