继承Thread类
1)定义一个类继承Thread,并重写Thread类的run方法
2)创建该类的对象,并调用该对象的start方法
例如:
public class ThreadTest {
public static void main(String[] args) {
NewThread t1 = new NewThread();
t1.start();
for(int i=0;i<100;i++) {
if(i%2==0) {
System.out.println(i);
}
}
}
}
class NewThread extends Thread {
@Override
public void run() {
for(int i=0;i<100;i++) {
if(i%2==1) {
System.out.println(i);
}
}
}
}
注意
-
想要启动多线程,必须调用start方法。如果自己手动调用run()方法,那么就只是普通方法,没有启动多线程模式。
-
一个线程对象只能调用一次start()方法启动,如果重复调用了,则将抛出以上 的异常“IllegalThreadStateException”。
-
run()方法由JVM调用,什么时候调用,执行的过程控制都有操作系统的CPU 调度决定。
实现Runnable接口
1)定义一个类实现Runnable接口,并重写Runnable接口的run方法
2)将Runnable接口的子类对象作为实际参数传递给Thread类的构造器中
3)调用Thread类的start方法
public class ThreadTest {
public static void main(String[] args) {
NewThread2 t1 = new NewThread2();
new Thread(t1).start();
for(int i=0;i<100;i++) {
if(i%2==0) {
System.out.println(i);
}
}
}
}
class NewThread2 implements Runnable {
@Override
public void run() {
for(int i=0;i<100;i++) {
if(i%2==1) {
System.out.println(i);
}
}
}
}
与第一种相比较:
- 避免了单继承的局限性
- 多个线程可以共享同一个接口实现类的对象,非常适合多个相同线 程来处理同一份资源。
实现Callable接口
public class ThreadTest {
public static void main(String[] args) {
FutureTask<Integer> futureTask = new FutureTask<Integer>(new NewThread3());
new Thread(futureTask).start();
try {
Integer value = futureTask.get();
System.out.println(value);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
class NewThread3 implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int sum=0;
for(int i=0;i<=100;i++) {
sum+=i;
}
Thread.sleep(10000);
return sum;
}
}
与使用Runnable相比, Callable功能更强大些
- 相比run()方法,可以有返回值
- 方法可以抛出异常
- 支持泛型的返回值
- 需要借助FutureTask类
使用线程池
ExecutorService:真正的线程池接口。常见子类ThreadPoolExecutor
void execute(Runnable command) :执行任务/命令,没有返回值,一般用来执行
- Runnable Future submit(Callable task):执行任务,有返回值,一般又来执行
- Callable void shutdown() :关闭连接池
Executors:工具类、线程池的工厂类,用于创建并返回不同类型的线程池
-
Executors.newCachedThreadPool():创建一个可根据需要创建新线程的线程池
-
Executors.newFixedThreadPool(n); 创建一个可重用固定线程数的线程池
-
Executors.newSingleThreadExecutor() :创建一个只有一个线程的线程池
-
Executors.newScheduledThreadPool(n):创建一个线程池,它可安排在给定延迟后运
行命令或者定期地执行。
public class ThreadTest {
public static void main(String[] args) {
// 1.调用Executors的newFixedThreadPool(),返回指定线程数量的ExecutorService
ExecutorService pool = Executors.newFixedThreadPool(10);
// 2.将Runnable实现类的对象作为形参传递给ExecutorService的execute方法开启线程
pool.execute(new NewThread());
pool.execute(new NewThread());
pool.execute(new NewThread());
// 3.结束线程的使用
pool.shutdown();
}
}