本文共 2952 字,大约阅读时间需要 9 分钟。
今天我们来学习多线程,首先我们要知道什么是线程? 线程与进程又有什么区别?
1.线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一个进程在运行时,是有多个线程一起运作的。 2.进程是静态的,线程是动态的。那么我们为什么要学习多线程呢?我们知道在我们代码的运行时,是逐行运行的,这样的方式效率很低,如果我们将互不干扰的两段代码分开去执行,就会大大减少代码的执行时间,提高效率。那么,就出现了多线程。
在学习多线程之前,我们还要了解并发与并行的区别。
并行:多个cpu实例或者多台机器同时执行一段处理逻辑,是真正的同时。 并发:通过cpu调度算法,让用户看上去同时执行,实际上从cpu操作层面不是真正的同时。只是电脑运行的速度特别快,让我们感觉是在同时运行。下面我们就来先学习多线程的三种创建方式:
方式一:继承Thread类
/** * 线程创建方式一: * 1.继承Thread类 * 2.重写run方法 * 3.开启线程 *///1.继承Thread类public class TestNewThread01 extends Thread{ //2.重写run方法 @Override public void run() { //run方法里面写线程主体 for (int i = 0; i < 10; i++) { System.out.println("这里是-------->新线程"); } } //主线程 public static void main(String[] args) { //3.在main线程里开启线程 new TestNewThread01().start(); System.out.println("main线程"); }}
在我们Java中,我们知道,Java只能单继承,如果一个类已经继承了一个类,那么这个类就不能去继承别的类了。但是我们Java可以多实现。所以我们为了提高多线程的扩展性,我们也可以使用第二种方式创建线程,当然在以后使用多线程的时候我们也推荐使用第二种方式。
方式二:实现Runnable接口
/** * 创建线程方式二: * 1.实现Runnable接口 * 2.重写run方法 * 3.借助静态代理模式开启线程 *///1.实现Runnable接口public class TestNewThread02 implements Runnable{ //2.重写run方法 @Override public void run() { //这里是线程体 for (int i = 0; i < 10; i++) { System.out.println("一个新的线程"); } } //主线程 public static void main(String[] args) { //3.使用静态代理模式开启线程 TestNewThread02 thread02 = new TestNewThread02(); Thread t = new Thread(thread02); t.start(); System.out.println("main线程"); }}
我们发现,使用实现Runnable接口这种方式已经可以满足我们大部分需求了,但是但我们想要线程有一个返回值时,这个方式二就不行了,所以就出现了第三种方式
方式三:实现Callable接口
/** * 创建线程方式三: * 1.实现Calloble接口 * 2.重写call方法 * 3.开启线程 *///1.实现Callable接口,这里需要一个泛型,是实现Callable接口返回值的类型public class TestNewThread03 implements Callable{ //2.实现call方法 @Override public Integer call() throws Exception { //线程体 int a = 10; int b = 20; int r = a+b; return r; } //主线程 public static void main(String[] args) throws ExecutionException, InterruptedException { //3.开启线程 //获取线程对象 TestNewThread03 t1 = new TestNewThread03(); TestNewThread03 t2 = new TestNewThread03(); TestNewThread03 t3 = new TestNewThread03(); //创建服务,参数是线程对象的个数 ExecutorService service = Executors.newFixedThreadPool(3); //提交线程,提交后会自动开启 Future r1 = service.submit(t1); Future r2 = service.submit(t2); Future r3 = service.submit(t3); //获取返回值 Integer i1 = r1.get(); Integer i2 = r2.get(); Integer i3 = r3.get(); System.out.println(i1); System.out.println(i2); System.out.println(i3); //关闭服务 service.shutdown(); }}
第三种方式虽然实现起来较为麻烦,但是好处是它有返回值,而且关联服务,如果在以后的开发中,我们有这种需求,我们就是用第三种方式。当然,一般情况下我们都会使用第二种方式,实现起来较为容易,扩展性也比比继承Thread类要好。
转载地址:http://rxiwi.baihongyu.com/