继承Thread
(1)定义Thread类的子类,重写该类的run方法,该run方法的方法体就代表了线程要完成的任务。因此把run()方法称为执行体。
(2)创建Thread子类的实例,即创建了线程对象。
(3)调用线程对象的start()方法来启动该线程。
class thread extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
public class ThreadTest1 {
public static void main(String[] args){
System.out.println(Thread.currentThread().getName());
for(int i = 0;i<5;i++){
new thread().start();
}
}
}
实现Runnable接口
(1)定义runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体是该线程的线程执行体。
(2)创建 Runnable实现类的实例,并依此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。
(3)调用线程对象的start()方法来启动该线程。
class ThreadRunnable implements Runnable {
@Override
public void run() {
//System.out.println(Thread.currentThread().getName());
//这里直接使用this,指向当前线程, 这也是通过继承Thread类创建线程的好处,不需要使用Thread.currentThread()来获取当前线程
System.out.println(this.getName());
}
}
public class ThreadTest3 {
public static void main(String[] args){
System.out.println(Thread.currentThread().getName());
for(int i = 0;i<5;i++){
ThreadRunnable threadRunnable = new ThreadRunnable();
new Thread(threadRunnable).start();
}
}
}
也可以使用匿名内部类的方式
public class ThreadTest2 {
public static void main(String[] args){
System.out.println(Thread.currentThread().getName());
for(int i = 0;i<5;i++){
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}).start();
}
}
}
使用Callable和FutureTask
(1)创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且有返回值。
(2)创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。
(3)使用FutureTask对象作为Thread对象的target创建并启动新线程。
(4)调用FutureTask对象的get()方法来获得子线程执行结束后的返回值
class CallableThread implements Callable<Integer>{
private Integer score;
public CallableThread(int score){
this.score = score;
}
@Override
public Integer call() throws Exception {
return score;
}
}
public class ThreadTest4 {
public static void main(String[] args){
System.out.println(Thread.currentThread().getName());
CallableThread callableThread = new CallableThread(100);
FutureTask<Integer> ft = new FutureTask<Integer>(callableThread);
new Thread(ft,"with back result").start();
try {
System.out.println(ft.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
其实这个方法严格意义上不能说是创建了线程的方式,因为真正创建还是通过new Thread()来实现的。
比较
接口可以实现多继承,所以当实现Runnable或者是Callable接口的方式创建线程时,还可以实现其他接口或者继承其他的类。同时,这种方式,多个线程多个线程可以共享同一个target对象,非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。
如果是通过继承Thread类来创建线程,则不可以再继承其他类。