一. 继承 Thread 类创建线程
- 可以通过 getId getName 方法获得线程 “ID” 和 “线程名”
- 使用继承 Thread 类的方式来创建线程时, 多个线程之间无法共享线程类的实例变量
public class MyThread extends Thread{@Overridepublic void run() {for(int i = 0; i < 10; ++i){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(i + ": 线程ID: "+ getId() + " 线程名: " + getName());}}
}
public static void thread(){//Thread 方式创建MyThread thread = new MyThread("线程名");thread.start();
}
二. 实现 Runnable 接口创建线程
- 只能通过 Thread.currentThread().getName() Thread.currentThread.getId() 获取线程 “ID” 和 “线程名”
public class MyRunnable implements Runnable {@Overridepublic void run() {for(int i= 0 ; i < 10; ++i){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " " + i);}}
}
public static void runnable(){//Runnable 方式MyRunnable runnable = new MyRunnable();Thread runnableThread = new Thread(runnable, "线程名");runnableThread.start();
}
- 可以使用 Lambda 表达式创建 Runnable 对象
public runnableLambda(){Thread thread = new Thread((Runnable)() -> {for(int i = 0; i < 100; ++i){System.out.println(Thread.currentThread().getName() + " " + i);}}, "线程名").start();
}
- Runnable 接口创建的线程可以共享线程类的实例变量
//Runnable 共享线程类实例变量
public static void runnableShare(){Runnable runnable = new Runnable(){private int i = 0;@Overridepublic void run() {for(; i < 100; ++i){System.out.println(Thread.currentThread().getName() + " " + i);}}};new Thread(runnable, "线程1").start();new Thread(runnable, "线程2").start();
}输出:线程1 96线程2 97线程1 98线程2 99
三. 使用 Callable 和 Future 创建线程
- 只能通过 Thread.currentThread().getName() Thread.currentThread.getId() 获取线程 “ID” 和 “线程名”
- Callable 接口提供了一个 call() 方法可以作为线程的执行体, 但 call() 方法比 run() 方法功能强大.
- call() 方法可以有返回值
- call() 方法可以声明抛出异常
- Future 接口来代表 Callable 接口里 call() 方法的返回值, 并且为 Future 接口提供了一个 FutureTask 实现类
public class MyCallable implements Callable {@Overridepublic Integer call() {int i = 0;for(; i < 10; ++i){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " 的循环变量i的值: " + i);}return i;}
}
public static void callable(){//Callable Future 方式FutureTask task = new FutureTask(new MyCallable());new Thread(task, "有返回值的线程").start();try {System.out.println("返回值: " + task.get());} catch (Exception e) {e.printStackTrace();}
}
- 可以使用 Lambda 表达式创建 Callable 对象
public static void callableLambda(){//Callable future Lambda 方式FutureTask task = new FutureTask((Callable)() -> {int i = 0;for(; i < 100; ++i){System.out.println(Thread.currentThread().getName() + " 的循环变量i的值: " + i);}return i;});new Thread(task, "有返回值的线程").start();try {System.out.println("获取子线程的返回值:" + task.get());} catch (Exception e) {e.printStackTrace();}
}
四. 三种方式的对比
- 采用 Runnable, Callable 接口的方式创建线程的优缺点:
- 线程类只是实现了上述接口, 还可以继承其他类
- 在这种情况下, 多线程可以共享同一个目标对象, 所以非常适合多个相同线程来处理同一份资源的情况,从而将CPU, 代码和数据分开, 形成清晰的模型,较好的体现了面向对象的思想
- 劣势: 编程稍微复杂
- 采用 Thread 类的方式创建多线程优缺点:
- 劣势: 因为已经继承 Thread 类, 所以无法继承其他类
- 优势: 编写简单
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!