1.why?
在程序中如果没有主动创建,只会存在一个主线程(但是在JVM中不止一个线程,还有诸如垃圾回收等)
所以为了提升性能aka加速,java开发中通常需要创建线程
2.how?
方法一:继承Thread类并重写run()
public class TestDemo{
public static void main(String args[]) {
new ThreadTest().start(); //新建一个实例并调用start()开始线程
}
}
class ThreadTest extends Thread{ //创建一个继承Thread的新类
static int[] i = {0,1,2,3};
@Override
public void run() { //新线程的入口,本质上也是实现了runable接口
for(int x:i)
{
System.out.println(x);
}
}
}方法二:继承Runable接口并重写run()
public class TestDemo{
public static void main(String args[]) {
RunnableTest r = new RunnableTest();
new Thread(r,"thread_1").start();
new Thread(r,"thread_2").start();
}
}
class RunnableTest implements Runnable{
static int[] i = {0,1,2,3};
@Override
public void run() {
for(int x:i)
{
System.out.println(x);
}
}
}方法三:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class TestDemo{
public static void main(String args[]) {
CallableTest c = new CallableTest();//创建 Callable 实现类的实例
FutureTask<Integer> f = new FutureTask<>(c); //FutureTask 类来包装Callable对象,并封装返回值
new Thread(f).start(); //使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程
try {
//调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。
System.out.println("子线程的返回值: " + f.get()); //FutureTask对象的get()要配合异常捕获语句使用
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
class CallableTest implements Callable{ //通过继承Callable接口创建实现类
static int[] i = {0,1,2,3};
@Override
public Integer call() throws Exception{ //重写的call()方法将作为线程执行体,并且有返回值
//throws Exception放在方法后边,表示的是本方法不处理异常,交给被调用处处理
int t = 0;
for(int x:i)
{
System.out.println(x);
t++;
}
System.out.println(Thread.currentThread().getName() + " is running");
return t;
}
}3.优劣比较
直接继承Thread类并重写run方法:编写简单,访问当前线程无需使用 Thread.currentThread() 方法,直接使用 this 即可;但已经继承了Thread,就不可以继承其他父类
runnable/callable:可以实现多继承,多个线程可以共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想
runnable与callable的区别:
(1) Callable重写的是call(),Runnable重写的是run()。
(2) Callable的任务执行后可返回值,而Runnable不能。
(3) call方法可以抛出异常,run方法不可以。
(4) 运行Callable任务可以拿到一个Future对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果

京公网安备 11010502036488号