关于线程创建的常用的3种方式
- 继承Thread类,重写run方法。
public class Demo1 {
public static void main(String[] args) {
Thread t1 =new Thread1();
Thread t2=new Thread2();
t1.start();
t2.start();
}
}
class Thread1 extends Thread{
@Override
public void run() {
for(int i=0;i<10;i++){
System.out.println("This is thread1 number:"+i);
}
}
}
class Thread2 extends Thread{
@Override
public void run() {
for(int i=0;i<10;i++){
System.out.println("This is thread2 number:"+i);
}
}
}
- 实现Runnable接口,并重写run方法。
public class Demo2 {
public static void main(String[] args) {
Thread t1=new Thread(new ThreadRunnable1());
Thread t2=new Thread(new ThreadRunnable2());
t1.start();
t2.start();
}
}
class ThreadRunnable1 implements Runnable{
@Override
public void run() {
for(int i=0;i<10;i++){
System.out.println("This is runnable thread1 number:"+i);
}
}
}
class ThreadRunnable2 implements Runnable{
@Override
public void run() {
for(int i=0;i<10;i++){
System.out.println("This is runnable thread2 number:"+i);
}
}
}
- 实现Callable接口,实现call方法,通过FutureTask将其包装后交由Thread执行线程。
public class Demo3 {
public static void main(String[] args)throws Exception {
Callable<String> callable1=new ThreadCallable1();
FutureTask task1=new FutureTask(callable1);
Thread thread1=new Thread(task1);
Callable<String> callable2=new ThreadCallable2();
FutureTask task2=new FutureTask(callable2);
Thread thread2=new Thread(task2);
thread1.start();
thread2.start();
// 最多等待线程执行10秒,如果10秒后线程还未执行完成,则会抛出TimeoutException
System.out.println(task1.get(10,TimeUnit.SECONDS));
System.out.println(task2.get(10,TimeUnit.SECONDS));
}
}
class ThreadCallable1 implements Callable<String> {
@Override
public String call() throws Exception {
for(int i=0;i<10;i++){
System.out.println("This is callable thread1 number:"+i);
}
return "Callable thread1 finish";
}
}
class ThreadCallable2 implements Callable<String> {
@Override
public String call() throws Exception {
for(int i=0;i<10;i++){
System.out.println("This is callable thread2 number:"+i);
}
return "Callable thread2 finish";
}
}
关于上述创建线程的3种方式,有以下几点总结:
- Thread类本身实现了Runnable接口,当我们创建的继承自Thread的线程类,并重写了run方法后,线程启动后就会调用传递进Thread的目标对象的run方法,进而开始执行线程处理。如下是Thread类中的run方法实现:
@Override
public void run() {
// target即为传递给线程Thread的目标对象,也就是上面示例中的thread1和thread2
if (target != null) {
target.run();
}
}
- 通过继承Thread和实现Runnable接口创建的线程,其没有返回值;通过实现Callable接口创建的线程,是可以在线程完成后返回想要的数据。