JAVA基础-线程
一、如何实现线程
1、实现Runable接口
public class RunnableDemo implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
System.out.println("this is a Runable Demo");
}
}
2、继承Thread类
public class ThreadDemo extends Thread {
private final int number;
public ThreadDemo(int number) {
this.number = number;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
System.out.println("this is extend Thread Demo, number is :" + number);
}
}
3、线程执行
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new ThreadDemo(1);
thread1.start();
//为了让线程按照顺序执行,用线程的join方法,阻塞线程
//实际使用的时候,如果没有严格的顺序需求,不推荐
thread1.join();
Thread thread2 = new Thread(new RunnableDemo());
thread2.start();
thread2.join();
System.out.println(Thread.currentThread().getName());
System.out.println("this is main thread");
}
}
运行结果:
Thread-0
this is extend Thread Demo, number is :1
Thread-1
this is a Runable Demo
main
this is main thread
启动线程的方法有2中start() 和run(),
用start启动才能新建线程,如上面运行结果Thread-0,thread-1, main
用run启动不会新建线程,上面运行结果为main,main,main
二、如何拿到线程中的返回结果
利用callable接口和futureTask来实现
1、实现Callable
public class CallableDemo implements Callable {
private String name;
public CallableDemo(String name) {
this.name = name;
}
@Override
public String call() throws Exception {
System.out.println(Thread.currentThread().getName());
System.out.println("this thread will sleep");
Thread.sleep(2000);
System.out.println("this thread wake");
return "this is a CallabelDemo's name is : " + name;
}
}
2、调用Futuretask
public class ThreadLearn {
public static void main(String[] args) throws Exception {
FutureTask<String> callTask = new FutureTask<String>(new CallableDemo("call"));
Thread callThread = new Thread(callTask);
callThread.start();
System.out.println(callTask.get());
}
}
执行结果:
Thread-0
this thread will sleep
this thread wake
this is a CallabelDemo’s name is : call
需要注意的是使用futuretask的get()方法来得到结果会一直阻塞主线程,直到拿到结果,如上面的例子,在callable的线程中让sleep了2s,但是在主线程中并没有让主线程休眠,正常情况下是主线程启动了新的线程后,如果callTask.get()没有阻塞主线程,那么主线程就已经结束,那么新起的线程也会因主线程结束而被回收,不会打印出来下面这2句。而结果是打印出来,验证看上面的说法
this thread wake
this is a CallabelDemo’s name is : call
针对get的这一特性,在用callable的时候需要自己callable里面加上超时或者异常处理。避免程序一直阻塞