【java多线程】多线程的建立三种方式--笔记

申明:线程的概念以及进程的相关概念,能够参考网络上其余资料,这里只讨论多线程是怎么实现。java

1、多线程的简单理解网络

 

明白什么是多线程,小生通俗一点的理解为:在一个程序里,我想同时让这个程序完成多个任务。多线程

好比:让主函数 main 在打印1~100之间的全部整数的时候,要求在主函数打印到 20 的时候,再运行另外一个类里的程序,让它打印10~100之间的全部整数。jvm

这里忽略同进程内的多线程之间的抢占时间问题,上面的举例需求是要求一个程序只要有发生同时运行俩个程序的状况就行,即不许出现不管程序跑多少次都是先把 main 函数的1~100 的全部整数打印完再打印10~100 之间的全部整数(PS:若是是这样的话,那就是 main 调用其余类的方法,属于单线程了)。ide

 

2、建立多线程的三种方式(小生写的比较繁缀罗嗦,建议阅读完以后,参考代码再阅读一次。)函数

 

第一种方式:this

建立:编写一个类 MyThread1 (这里只是小生的自定义命名,方便与代码里名称一致)让它继承 Thread 类,编码

并把须要多线程运行的程序放到 public void run() 方法里。spa

启动:在主函数中,new 出 MyThread1 类的实例。线程

运行:调用 MyThread1 类的实例的 start() 方法便可。

第二种方式:

建立:编写一个类 MyThread2 让它实现 Runnable 接口,而且要重写 run() 方法(把须要多线程运行的程序放到 public void run() 方法里)。

启动:在主函数中,new 出 MyThread1 类的实例,

new 出Thread 类(带有 target 的构造方法),

把MyThread1 类的实例做为参数传入Thread 类的构造方法里。

运行:调用 Thread 类的实例的 start() 方法便可。

第三种方式:

建立:实现 Callable 接口(小生定义这个类为 MyCallable),而且实现 call() 方法,注意 call() 方法是有返回值的。

启动:new 出Callable 接口的实现类MyCallable,

new 出 FutureTask 类的实例 task,

把call() 方法的返回值放入FutureTask 类的构造方法里,

把 task 放入 new 出的 Thread 构造方法里。

运行:调用 Thread 类的实例的 start() 方法便可。

 

三种方式的利弊总结:

  第一种方法好处:建立已经继承 Thread 类的类的实例,调用 start() 方法就能运行,代码写起来很方便,

    固然缺点就是继承了Thread 父类,就没有办法继承其余的类了,扩展性很差。因此通常不建议用这种方式建立多线程。

  第二种方法好处:继承接口,扩展性好。

    弊端是相对的,第一种方式很差也是相对于第二种来讲的,而第二种方式相比第三种方式来讲,run() 方法没有返回值,而且不能申明抛出异常。

  第三种方式好处上面已经说明,很差的就是编码很麻烦(小生太笨看了半天才搞明白)

 

4、建立多线程的三种方式的代码演示

说明:小生会对每种方式的每条线程进行重命名,只是为了方便代码运行效果演示。

java 默认线程的名称规则:java 中的 main 函数自己就是一个默认的主线程,名字为:main(在下面例子能够证明 main 线程在 jvm 中的默认名称)

若是本身定义的线程没有定义名称,则系统默认按照 Thread-0,Thread-1,……的命名方式进行命名。也能够经过对线程的构造方法进行重命名。

 

4.1 继承 Thread 类

  偷窥一下 API 发现 Thread 类实现了 Runnable 接口,currentThread() 静态方法返回当前线程这个实例,再 getName() 一下就获得当前线程的名字了。

       

   

  

  MyThread1 线程:

 1 package com.test.threadDemo1;
 2 
 3 public class MyThread1 extends Thread {
 4     
 5     public MyThread1(String name) {
 6         this.setName(name);
 7     }
 8 
 9     public void run() {
10         for(int i=20;i<=100;i++) {
11             System.out.println(getName()+"..."+i);
12         }
13     }
14 }

  main 线程:

 1 package com.test.threadDemo1;
 2 /**
 3  * 多线程的实现之一:继承 Thread 类
 4  * @author Administrator
 5  *
 6  */
 7 public class ThreadDemo1 {
 8     public static void main(String[] args) {
 9         for (int i=1;i<=100;i++) {
10             System.out.println(Thread.currentThread().getName()+"..."+i);
11             
12             if(i==30) {
13                 MyThread1 myThread = new MyThread1("新线程");
14                 myThread.start();
15             }
16         }
17     }
18 }

  运行结果:(有交叉运行的状况发生,就是多线程了)

  从结果能够看出,当 main 线程跑到 30 的时候还在“抢占” CPU

  

4.2 实现 Runable 接口

  MyThread 线程:

 1 package com.test.threadDemo1;
 2 
 3 public class MyThread2 implements Runnable {
 4     
 5     public MyThread2(String name) {
 6         Thread.currentThread().setName(name);
 7     }
 8     
 9     @Override
10     public void run() {
11         for(int i=20;i<=100;i++) {
12             System.out.println(Thread.currentThread().getName()+"..."+i);
13         }
14     }
15     
16 }

  main 线程:

 1 package com.test.threadDemo1;
 2 /**
 3  * 多线程的实现之二:实现 Runable 接口
 4  * @author Administrator
 5  *
 6  */
 7 public class ThreadDemo2 {
 8     public static void main(String[] args) {
 9         for (int i=1;i<=100;i++) {
10             System.out.println(Thread.currentThread().getName()+"..."+i);
11             
12             if(i==30) {
13                 MyThread2 myThread = new MyThread2("新线程");
14                 
15                 Thread thread = new Thread(myThread);
16                 
17                 thread.start();
18             }
19         }
20     }
21 }

  运行结果:

  

4.3 实现 Callable 接口和 Future 接口

  Future接口的实现类是 FutureTask,它实现了 Runable 接口,因此可以做为 target 参数传到 Thread 类的构造方法里。

  FutureTask(Callable<V> callable)

  从构造方法里能够看出 FutureTask 的构造方法里传入 callable 的实现类就好了。

  MyThread3 线程:

 1 package com.test.threadDemo1;
 2 
 3 import java.util.concurrent.Callable;
 4 
 5 public class MyThread3 implements Callable<Integer> {
 6 
 7     @Override
 8     public Integer call() throws Exception {
 9         int i = 20;
10         for(;i<=100;i++) {
11             System.out.println(Thread.currentThread().getName()+"..."+i);
12         }
13         return i;
14     }
15 
16 }

  main 线程:

 1 package com.test.threadDemo1;
 2 
 3 import java.util.concurrent.Callable;
 4 import java.util.concurrent.FutureTask;
 5 
 6 /**
 7  * 多线程的实现之三:实现 Callable 接口和 Future 接口
 8  * @author Administrator
 9  *
10  */
11 public class ThreadDemo3 {
12     public static void main(String[] args) {
13         
14         Callable<Integer> myThread3 = new MyThread3();        
15         FutureTask<Integer> task = new FutureTask<Integer>(myThread3);
16         
17         for (int i=1;i<=100;i++) {
18             System.out.println(Thread.currentThread().getName()+"..."+i);
19             
20             if(i==30) {
21                                 
22                 Thread thread = new Thread(task,"新线程");
23                 thread.start();
24             }
25         }
26     }
27 }

  运行结果:

  

相关文章
相关标签/搜索