java启动线程的三种方式
1.继承 Thread类,重写run方法,调用start方法启动线程
2.实现Runnable接口,重写run方法,调用start方法启动线程
3.实现Callable接口
代码如下
前两种方式:
package club.jiajiajia;
/**
* 创建线程的两种方式
*/
public class Main {
public static void main(String[] args) {
//第一种 继承 Thread类,重写run方法,调用start方法启动线程
new Thread(){
@Override
public void run() {
while(true){
try {
Thread.sleep(500);
System.out.println("Thread name1:"+Thread.currentThread().getName());
//得到当前线程的线程名
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
//第二种 实现Runnable接口,重写run方法,调用start方法启动线程
new Thread(new Runnable() {
@Override
public void run() {
while(true){
try {
Thread.sleep(500);
System.out.println("Thread name2:"+Thread.currentThread().getName());
//得到当前线程的线程名
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
第三种方式:
package threadTest.test1;
import java.util.concurrent.Callable;
public class ThreadTest implements Callable<Integer>{
@Override
public Integer call() throws Exception {
// TODO Auto-generated method stub
//任务
//返回结果
return 1;
}
}
package threadTest.test1;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Test1 {
public static void main(String[] args) {
FutureTask<Integer> futureTask = new FutureTask<Integer>(new ThreadTest());
new Thread(futureTask).start();
try {
//接收结果
Integer sum = futureTask.get();
System.out.println(sum);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
接着再来看一个面试题
下面的代码执行情况是怎样的??
package club.jiajiajia;
public class Main2 {
public static void main(String args[]){
new Thread(new Runnable() {
@Override
public void run() {
while(true){
try {
Thread.sleep(500);
System.out.println("Thread name1:"+Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}){
@Override
public void run() {
while(true){
try {
Thread.sleep(500);
System.out.println("Thread name2:"+Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
}
那么答案当然是 重复打印:Thread name2:Thread-0
原因就是子类重写的方法会覆盖父类的方法,
走进Thread的run方法:

而targer就是我们传入的Runnable的实现类

所以Thread的run方法的代码将会被覆盖,不会再调用实现Runnable接口的run方法。