1.第一种方式: extends Thread
public class Test{
public static void main(String[] args) {
//3.创建Thread类的子类对象
ThreadTest threadTest1 = new ThreadTest();
//设置当前线程的名字
threadTest1.setName("线程1");
//4.启动当前线程
threadTest1.start();
}
}
//1.继承Thread类
class ThreadTest extends Thread{
//2.重写run()方法
@Override
public void run() {
for (int i = 0; i <= 100 ; i++) {
if (i % 2 ==0){
System.out.println(getName() + ":" + i);
}
}
}
}
总结:使用继承Thread类的方法来创建线程类,多个线程之间无法共享线程类的实例变量,可以共享线程类的静态变量,但是存在线程安全问题
2. 第二种方式: implements Runnable
public class Test{
public static void main(String[] args) {
//3.创建Runnable接口实现类的对象
RunnableTest runnableTest = new RunnableTest();
//4.将Runnable接口实现类的对象传入Thread构造器中
Thread thread = new Thread(runnableTest,"线程1");
//5.启动线程
thread.start();
}
}
//1.实现Runnable接口
class RunnableTest implements Runnable{
//2.实现run()方法
@Override
public void run() {
for (int i = 0; i <= 100 ; i++) {
if (i % 2 == 0){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
}
总结:使用实现Runnable的方法来创建线程类,多线程之间可以共享线程类的实例变量,但是存在线程安全问题
3.第三种方式: implements Callable
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Test{
public static void main(String[] args) {
//3.创建Callable实现类的对象
CallableTest callableTest = new CallableTest();
//4.将Callable实现类的对象传入FutureTask构造器中 (FutureTask是Runnable接口的实现类)
FutureTask<Integer> futureTask = new FutureTask<Integer>(callableTest);
//5.将FutureTask类中对象传入Thread构造器中
Thread thread = new Thread(futureTask, "线程1");
//6.启动线程
thread.start();
//7.获取call()方法的返回值
try {
Integer integer = futureTask.get();
System.out.println("0-100之间偶数的总和: " + integer);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
//1.实现Callable接口
class CallableTest implements Callable<Integer>{
//2.实现call()方法
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i <= 100 ; i++) {
if (i % 2 == 0){
System.out.println(Thread.currentThread().getName() + ":" + i);
sum += i;
}
}
return sum;
}
}
总结:使用实现Callable接口的方法来创建线程类,多线程之间可以共享线程类的实例变量,但是存在线程安全问题
4.第四种方式 线程池
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
public class Test{
public static void main(String[] args) {
//1.创建线程池(线程池有6种,详见文档Executors)
ExecutorService executorService = Executors.newFixedThreadPool(10);
//管理线程池(设置线程池的属性)
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executorService;
threadPoolExecutor.setCorePoolSize(10);
threadPoolExecutor.setMaximumPoolSize(10);
//2.创建一个线程对象(相当于告诉线程池,当前线程需要做什么任务)
ThreadPoolTest threadPoolTest = new ThreadPoolTest();
//3.将这个线程对象提交到线程池
executorService.submit(threadPoolTest);
//4.关闭线程池
executorService.shutdown();
}
}
class ThreadPoolTest implements Runnable{
@Override
public void run() {
for (int i = 0; i <= 100 ; i++) {
if (i % 2 == 0){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
}
总结: 开发中通常使用创建线程池的方式来启动线程
好处:
1.提高响应速度(减少了创建新线程的时间)
2.降低资源消耗(重复使用线程池中的线程)
3.便于线程的管理