继承Thread类实现多线程
public class ThreadTest01 {
public static void main(String[] args) {
//main方法,这里的代码属于主线程,在主栈中运行
MyThread myThread = new MyThread();
myThread.start();
//这里的代码还是运行在主线程中
for (int i = 0; i < 1000; i++) {
System.out.println("主线程--->" + i);
}
}
}
class MyThread extends Thread{
@Override
public void run() {
//编写程序,这端程序运行在分支栈中
for (int i = 0; i < 1000; i++) {
System.out.println("分支线程--->" + i);
}
}
}
start方法的作用是在JVM中开辟一个新的栈空间,启动一个分支线程,这段代码任务完成之后,瞬间就结束了
这段代码的任务只是为了开启一个新的栈空间,只要新的栈空间出来,start()方法就结束了.线程就启动成功了
启动成功的线程会自动调用run方法,并且run方法在分支栈的栈底部(压栈)
run方法在分支栈的地步,main方法在主栈的栈底部,run和main是评级的.
实现Runnable接口创建线程
当子类实现了Runnable接口,子类负责真实的业务操作,Thread负责资源调度以及线程的创建等真实业务,其原理是代理模式
文章: 代理模式
public class ThreadTest02 {
public static void main(String[] args) {
//采用接口的方式实现多线程.
Thread thread = new Thread(new MyRunnable());
thread.start();
for (int i = 0; i < 1000; i++) {
System.out.println("主线程--->" + i);
}
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("分支线程--->" + i);
}
}
}
重写Callable接口实现多线程
public class CallableTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//怎么启动Callable
MyThread thread = new MyThread();
FutureTask futureTask = new FutureTask(thread);
new Thread(futureTask,"A").start();
new Thread(futureTask,"B").start(); //启动两个线程 call方法只会执行一次,Callable本身存在缓存
Integer integer = (Integer) futureTask.get();//获取callable的返回结果
//这个get方法可能会产生阻塞,因为只有当线程执行完成之后才能获取返回值,或者使用异步处理
System.out.println(integer);
}
}
class MyThread implements Callable<Integer>{
@Override
public Integer call() throws Exception {
System.out.println("call()");
return 1024;
}
}
使用创建的 FutureTask 对象作为任务创建了一个线程并且启动它,最后通过 futureTask.get() 等待任务执行完毕返回结果