为什么要使用多线程
以前单任务的操作系统,当系统处理耗时的I/O操作的时候也是占用CPU,这种情况下系统的效率很低,现在使用多任务的操作系统,当一个任务处理耗时的操作时,CPU可以腾出来给别的任务,这样的话,CPU的利用率明显提高。好比,以前早上我们先洗漱,然后再去用电饭煲煮稀饭,现在我们可以一边用电饭煲煮稀饭,一边洗漱,等洗漱完直接吃热气腾腾的早餐,这样充分利用了我们有限的时间。
如何创建线程
继承Thread类
实现Runable接口
实现Callable接口
问题
-
继承Thread类和实现Runable接口或实现Callable接口创建线程的区别?
其实是问接口和继承的区别:简单一句话:优先使用接口,如果既要定义子类的行为,又要为子类提供公共的方法则使用继承。
实现Runable接口和实现Callable接口的区别
首先我们看一下这个两个接口的定义:
public interface Callable<V> {
V call() throws Exception;
}
public interface Runnable {
public abstract void run();
}
从接口定义可以看出:
Callabe使用call()方法,Runable使用run方法
call()又返回值,run()没有
call()可以抛出受检查的异常,比如ClassNotFoundException,而run()不能抛出受检查的异常
Thread的没有接受Callable的构造方法,使用Callable时需要FutureTask包装。
如何启动线程:
调用start方法
创建线程的Demo
/**
* 继承Thread类创建线程
*/
public class CreateThread1 extends Thread {
public static void main(String[] args) {
CreateThread1 thread1 = new CreateThread1();
//启动线程
thread1.start();
}
@Override
public void run() {
System.out.println("我是继承Thread类创建线程");
}
}
/**
* 实现Runnable接口创建线程(写法1)
*/
public class CreateThread2 {
public static void main(String[] args) {
Thread thread = new Thread(new MyThread());
thread.start();
}
}
class MyThread implements Runnable {
public void run() {
System.out.println("实现Runnable接口创建线程");
}
}
/**
* 实现Runnable接口创建线程(写法2)
*/
public class CreateThread2 {
public static void main(String[] args) {
new Thread(new Runnable() {
public void run() {
System.out.println("实现Runnable接口创建线程");
}
});
}
}
public class CallableTest implements Callable<String> {
public static void main(String[] args) throws Exception {
FutureTask futureTask = new FutureTask(new CallableTest());
new Thread(futureTask).start();
System.out.println("线程开始执行");
String result = (String) futureTask.get();
System.out.println(result);
}
@Override
public String call() throws Exception {
Thread.sleep(1000);
return "执行完成";
}
}