Java多线程实现方式:Thread,Runnable,Callable
多线程是乱序执行
Thread
===
1.Thread资源不可以共享
- .start()并不会让线程立即执行,而是令线程处于可运行状态(Runnable)具体执行时间由操作系统决定。
public class ThreadTest extends Thread {
private int num = 0;
@Override
public void run() {
for (int i= 0; i<10;i++) {
num +=1;
System.out.println(num);
}
}
public static void main(String[] args) {
ThreadTest thread1 = new ThreadTest();
ThreadTest thread2 = new ThreadTest();
thread1.start();
thread2.start();
}
}
Runnable
1.implements Runnable
2.Runnable在Thread的基础上实现了资源共享
3.Runnable 只有一个方法run,没有start方法,因此需要借助Thread进行线程启动
4.Runnable获取不到线程执行结果,同时无法抛出异常
public class RunableTest {
public static void main(String[] args) {
Run run = new Run();
Thread thread1 = new Thread(run);
Thread thread2 = new Thread(run);
thread1.start();
thread2.start();
}
}
class Add {
private int num;
public void add(int n) {
for (int i = 0;i < n;i++) {
num += 1;
System.out.println(num);
}
}
}
class Run implements Runnable {
private Add add = new Add();
public void run() {
add.add(10);
}
// public void run() {
// synchronized (add) {
// try {
// add.add(10);
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
// }
}
Callable
1.较Runnable功能更加强大,可以异步获取线程执行结果,返回值可以被FutureTask/Future拿到
2.FutureTask实现了Future和Runnable接口:所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。
3.可以通过Future.get()获取返回值,但是Future.get()是阻塞的,只有拿到当前进程的返回值才会获取下一个进程的返回值。
4.Future.get()有两个功能:1、判断Runnable是否成功执行完毕;2、获取Callable返回的结果因为是阻塞的,所以返回值顺序等同于现场的执行顺序。
4.执行Callable的方法:ExecutorService/ThreadPoolTaskExecutor