一、Java通过继承Thread类来创建,并重写run()方法
1.定义Thread的子类,并且重写run()方法
2.创建Thread子类的实例
3.调用该线程对象的start()方法来启动该线程
public class MyThread1 extends Thread{
public MyThread1(String name) {
super(name);
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
public class TestMyThread {
public static void main(String[] args) {
MyThread1 t1=new MyThread1("子线程1");
MyThread1 t2=new MyThread1("子线程2");
t1.start();
t2.start();
for (int i = 0; i < 100; i++) {
System.out.println("main线程:"+i);
}
}
}
二、Java通过实现Runnable接口,并重写run()方法
1.定义Runnable接口的实现类,并重写该接口的run()方法
2.创建Runnable实现类的实例,并以此实例作为Thread的target参数来创建Thread对象,该对象才是真正的线程对象
3.调用线程对象的start()方法,启动线程
public class MyThread2 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
public class TestMyThread {
public static void main(String[] args) {
MyThread2 mr=new MyThread2();
Thread t1=new Thread(mr,"子线程1");
Thread t2=new Thread(mr,"子线程2");
t1.start();
t2.start();
for (int i = 0; i < 100; i++) {
System.out.println("main线程:"+i);
}
}
}
三、Java实现Callable接口,并重写call()方法
1.定义Callable接口的实现类,并重写该接口的call()方法
2.创建Callable实现类的实例
3.线程对象作为参数传入FutureTask的含参构造器创建FutureTask对象
4.FutureTask对象作为参数传入Thread的含参构造器
5.调用Thread类的start()方法
public class MyThread3 implements Callable {
@Override
public Object call() throws Exception {
int sum=0;
for (int i = 0; i < 100; i++) {
sum+=i;
}
return sum;
}
}
public class TestMyThread {
public static void main(String[] args) {
MyThread3 mt=new MyThread3();
FutureTask futureTask = new FutureTask(mt);
Thread thread = new Thread(futureTask);
thread.start();
try {
Object sum = futureTask.get();
System.out.println("总和为:"+sum);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
实现Callable接口的方法相较于实现Runnable接口的方法
有返回值
方法可以抛出异常
支持泛型的返回值,需要借助FutureTask类,获取返回结果
四、使用线程池
1.定义Runnable接口的实现类,并重写该接口的run()方法
2.提供指定线程数量的线程池,通过Executors中的newFixedThreadPool()方法
3.使用execute()方法执行
4.使用shutdown()关闭连接池
public class MyThread4 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
public class TestMyThread {
public static void main(String[] args) {
ExecutorService threadPool = Executors.newFixedThreadPool(10);
threadPool.execute(new MyThread4());
threadPool.execute(new MyThread4());
threadPool.shutdown();
}
}
通过Thread创建的线程在执行完就被销毁,不能复用,在高并发场景中频繁创建线程非常消耗资源,通过线程池创建线程可以对已经创建好的线程进行复用,使用时直接获取,使用完后直接放回。