首先要区别Java中的线程和进程的区别:
1.进程时系统分配资源的最小单位,线程是系统调度的最小单位。
2.一个进程包含多个线程。
多线程的使用场景:
1.主要是为了提高性能,效率。
2.阻塞式代码导致后续代码无法执行的时候,使用多线程。
Java并发编程中有以下三种线程创建方式:
方法一:使用Thread()类来创建线程;
使用Thread类创建线程,并重写run()方法,调用start()方法来启动线程。调用了start方法后线程并没有马上执行,而是处于就绪状态,这个就绪状态是指线程已经获得了除过CPU资源外的其他资源,等待获取CPU资源后才会真正处于运行状态,分配CPU资源这个过程是由操作系统来为我们做的。一旦run方法执行完毕,线程就变为终止状态。
public class ThreadTest {
public static class MyThread extends Thread{
@Override
public void run() {
System.out.println("start");
//使用this来获取当前线程
System.out.println(this);
}
}
public static void main(String[] args) {
//创建线程
MyThread thread=new MyThread();
//启动线程
thread.start();
System.out.println("end");
}
}
方法二:继承Runnable()接口;
创建一个RunnableTask类实现Runnable接口,实现run()方法。
class RunnableTask implements Runnable{
@Override
public void run() {
System.out.println("start");
}
}
public class RunnableTest {
public static void main(String[] args) {
RunnableTask task=new RunnableTask();
new Thread(task).start();
new Thread(task).start();
System.out.println("88");
}
}
方法三:使用Callable()接口;
CallerTask类实现Callable接口的call()方法,并且在main函数中创建了一个FutureTask对象,然后使用创建的FutureTask对象作为任务创建一个线程并启动它,最后通过futureTask.get()等待任务执行完毕并返回结果。
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
class CallerTask implements Callable<String>{
@Override
public String call() throws Exception {
return "hello";
}
}
public class CallableTest {
public static void main(String[] args) {
//创建异步任务
FutureTask<String> futureTask=new FutureTask<>(new CallerTask());
//启动线程
new Thread(futureTask).start();
System.out.println("girl");
try{
//等待任务执行完毕,并返回结果
String result=futureTask.get();
System.out.println(result);
}catch (ExecutionException | InterruptedException exc){
exc.printStackTrace();
}
}
}
总结:
1.使用Thread创建线程的优势:
在run方法内获取当前线程直接使用this就可以了,无须使用Thread.currentThread()方法;
缺点:
Java不支持多继承,如果继承了Thread类,那么不能再继承其他的类。
任务和代码没有分离。
2 .使用Runnable接口创建线程的优点:
任务和代码分离开来,可以多个线程执行一样的任务,而不需要多份代码。
使用Runnable接口可以继承多个类。
缺点:
任务没有返回值。
3.Callable接口的优点:
可以使用FutureTask来接收线程的返回值。支持多继承。
缺点:返回当前线程必须调用Thread.currentThread(),不能使用this。