什么是线程
线程是操作系统能够进行运算调度的最小单位,它被包含在进程(内存中运行的应用程序,比如运行中的微信就是一个进程)中,是进程中的实际运作单位,与进程共享内存空间。一个进程中可以并发多个执行不同任务的线程,比如JVM在启动时,必定会有一个线程从main方法开始,一直到main方法结束
线程的三种创建方法:
1.继承Thread,例如以下代码:
MyThread类继承Thread类,然后重写Thread类中的run方法用来在控制台输入出数字0到9
public class MyThread extends Thread{
@Override
public void run(){ //重写Thread中的run方法
for(int i=0;i<10;i++){
Sytstem.out.println(i);
}
}
}
接着我们在Demo类中通过new MyThread()创建线程,然后调用start去启动这个线程让他执行在控制台输入出数字0到9的任务。
public class Demo{
public static void main(String[]args){
Thread t=new MyThread();
t.start();
}
}
2.实现Runnable类
首先我们需要实现Runnable类并同时实现它的抽象的run方法
public class MyRunnable implements Runnable{
@Override
public void run(){ //实现Runnable中的run方法
for(int i=0;i<10;i++){
Sytstem.out.println(i);
}
}
}
接着我们在Demo类中先创建一个任务r,接着在创建线程的时候把任务r作为参数传入,然后调用线程的start方法去启动
public class Demo{
public static void main(String[]args){
Runnable r=new MyRunnable(); //创建任务
Thread t=new MyThread(r); //创建线程
t.start();//启动线程
}
}
3.实现Callable类(和实现Runnable最大的区别就在于用这个方法可以让线程有返回值)
首先需要编写一个类来实现Callable接口(这里同时指定了泛型为Integer型,是为了让call方法返回Integer类型的返回值),并实现接口的call方法
public class MyCallable implements Callable<Integer>{
@Override
public Integer call() throws Exception{ //实现Callable中的call方法
for(int i=0;i<10;i++){
Sytstem.out.println(i);
}
return 0;
}
}
接着在Demo类中创建Callable对象c,然后创建FutureTask对象f,并传入对象c,最后启动线程t。这时JVM中有主线程main和子线程t在运行(当然还有垃圾回收线程),当主线程调用FutureTask的get()时,主线程将被阻塞直到子线程运行完,所以后面的for代码将在子线程运行完后再运行。
public class Demo{
public static void main(String[]args){
Callable c=new MyCallable();//创建Callable对象c
FutureTask<Integer> f=new FutureTask<>(c);//创建FutureTask对象f并传入对象c
Thread t=new MyThread(f); //创建线程,并传入对象f
t.start();//启动线程
f.isDone();//用来任务c是否执行完毕
f.get(); //调用get方法后,main线程会等子线程运行完后再继续下面的代码
for(int j=0;j<10;j++){
System.out.println(j);
}
}
}