Java创建线程的三种方式
1、继承Thread类
此方式创建多线程简单易懂,但是同时代码量也大大增加。
每个线程或许只进行一个操作也需要创建一个新的类去继承Thread类,且只能继承Thread类。
获取线程简单,直接使用this即可
不能在run方法中抛出异常
// 继承Thread类创建线程:线程只能单继承,每个不同的操作都要一个新的类
public class ThreadTest extends Thread {
public ThreadTest(String name) {
super(name);
}
static int i = 0;
@Override
public void run() {
for (; i < 100; i++) {
System.out.println("线程名称:" + this.getName() + "index:" + i);
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Thread thread = new ThreadTest("1 - ");
Thread thread2 = new ThreadTest("2 - ");
thread2.start();
thread.start();
}
}
2、实现Runnable接口
线程可以继承其他的类,且jdk8之后可以不用创建新的类就可实现多线程,编写简单,大大减少代码量。个人比较倾向于此方式创建线程
访问当前线程较麻烦:Thread.currentThread()
不能在run方法中抛出异常
// Runnable创建多线程特点:可以多实现,减少代码量
public class RunnableTest implements Runnable {
static int index = 0;
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("线程名称:" + Thread.currentThread().getName() + "index: " + index);
index++;
}
}
public static void main(String[] args) {
Thread thread = new Thread(new RunnableTest(), "1 - >>> ");
Thread thread2 = new Thread(new RunnableTest(), "2 - >>> ");
// jdk1.8后实现Runnable接口创建线程的写法
Thread thread3 = new Thread(() -> {
for (int i = 0; i < 100; i++) {
System.out.println("线程名称:" + Thread.currentThread().getName() + "index: " + index);
index++;
}
}, "3 - >>>");
thread3.start();
thread.start();
thread2.start();
}
}
3、实现Callable接口
这种方式最大的特点就是可以获取到线程执行完成后的返回值
可以在call方法中抛出异常,这也是以上两种方式不能实现的
也可以继承其他父类,获取线程也比较繁琐,和runnable方式一样
/**
* 实现callable创建多线程特点:
* 可以有返回值,可以在call方法中抛出异常
*/
public class CallableTest implements Callable<String> {
static int index = 0;
@Override
public String call() throws Exception {
for (int i = 0; i < 10; i++){
System.out.println("当前线程:" + Thread.currentThread().getName() + " --- " + index );
index--;
}
return Thread.currentThread().getName() + "index: " + index;
}
public static void main(String[] args) {
CallableTest callableTest = new CallableTest();
FutureTask<String> futureTask = new FutureTask<>(callableTest);
FutureTask<String> future = new FutureTask<>(callableTest);
// 每次传入Thread的future不能是同一个,如果传入同一个future的话并不能实现多线程
// 但是可以两个future对象中的参数可以是同一个callable的的对象,也可以实现多线程
new Thread(futureTask, "1 - ").start();
new Thread(future, "2 - ").start();
try {
System.out.println(future.get());
System.out.println(futureTask.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
以上内容均属个人练习与理解,仅供参考