线程:一个进程中的执行路径,一个进程可以包含多个线程,线程之间共享一个内存空间,并发执行。一个进程最少有一个线程。
在java是抢占式线程机制
在java中使用线程的三种方式
1、继承Thread
// 在java中使用线程的第一种方式 // 直接继承thread类 重写thread的run方法 class Demo extends Thread{ @Override public void run(){ // 这里是一个线程 通过thread对象的start方法启动任务(自动调用run方法) for(int i = 0; i < 10; i++){ System.out.println(i); } } }
// 测试类 // main方法中的循环与Demo的循环会同时交替执行(抢占时间篇) public class Text{ public static void main(String[] args){ Demo thread = new Demo(); thread.start(); for(int i = 0; i < 10; i++){ System.out.println(i); } //或者通过以下匿名内部类方法 new Thread(){ @Override public void run(){ for(int i = 0; i < 10; i++){ System.out.println(i); } } }.start(); } }
2、实现Runnable(与继承Thread相比有以下优势)
通过创建任务,分配给线程执行,更适合多个线程同时执行相同的任务情况
可以避免单继承所带来的局限性
任务与线程本身是分离的,提高程序健壮性
// 实现Runnable 创建一个用来给线程执行的任务 public class Demo implements Runnable{ @Override public void run(){ // 需要线程执行的任务 for(int i = 0;i < 10; i++){ System.out.println(i); } } }
// 测试类 // 与上一个例子执行效果相同 public class Test{ public static void main(String[] args){ // 将创建好的任务对象传给线程执行 Demo runnable = new Demo(); Thread newthread = new Thread(runnable); newthread.start(); for(int i = 0; i < 10; i++){ System.out.println(i); } } }
3、callable(类似于Runnable)
Callable 与 Runnable 的区别是
Callable 允许抛出异常
Callable 又返沪值// Callable 与 Runnable 的区别是 // Callable 允许抛出异常 // Callable 又返沪值 public class Demo implements Callable{ @Override public Integer call() throws Exception{ return 100; } }
// 测试类 public class Test{ public static void main(String[] args){ Callable<Integer> myCallable = new Demo(); // 创建一个Callable的任务 FutureTask<Integer> task = new FutureTask<>(myCallable); // 调用线程执行 new Thread(task).start(); // 获取线程返回值(主线程会停止等待线程返回值) Integer result = task.get(); } }