Java基础之多线程框架(二)

1、前言   

      当一个Java程序启动的时候,一个线程就马上启动,改程序一般也被咱们称做程序的主线程。其余全部的子线程都是由主线程产生的。主线程是程序开始就执行的,而且程序最终是以主线程的结束而结束的。java

      Java编写程序都运行在在Java虚拟机(JVM)中,在JVM的内部,程序的多任务是经过线程来实现的。每用Java命令启动一个Java应用程序,就会启动一个JVM进程。在同一个JVM进程中,有且只有一个进程,就是它本身。在这个JVM环境中,全部程序代码的运行都是以线程来运行。多线程

2、多线程的概念 框架

      一般,咱们接触的简单的程序都是单线程的,可是若是咱们须要进行“多线操做”的话,就须要借助多线程来实现了,对于一个进程中的多个线程来讲,多个线程共享进程的内存块,当有新的线程产生的时候,操做系统不分配新的内存,而是让新线程共享原有的进程块的内存。所以,线程间的通讯很容易,速度也很快。不一样的进程由于处于不一样的内存块,所以进程之间的通讯相对困难。this

     在Java中,多线程的实现有两种方式:继承java.lang.Thread类;实现java.lang.Runnable接口。spa

3、继承Thread类来实现多线程操作系统

      当一个类继承Thread类时,在类中必须重载run()方法,同时这个run()方法也是线程的入口,在调用的过程当中,经过调用start()方法来启动新线程,其基本框架为:线程

1 class 类名 extends Thread{
 2 方法1;
 3 方法2;
 4 …
 5 public void run(){
 6 // other code…
 7 }
 8 属性1;
 9 属性2;
10 …
11  
12 }

        在这里,咱们用一个简单的窗口买票的例子来实现此类多线程设计

1 class TestThread extends Thread
 2 {
 3     private String name;
 4     public TestThread(String name)
 5     {
 6         this.name=name;
 7     }
 8     public void run()
 9     {
10 
11         for (int i = 0; i < 7; i++)
12         {
13             if (num > 0)
14             {
15                 System.out.println(name+"正在卖票  "+"num= " + num--);
16             }
17         }
18     }
19 
20 
21     public static void main(String[] args)
22     {
23 
24         TestThread h1 = new TestThread("窗口1");
25         TestThread h2 = new TestThread("窗口2");
26         TestThread h3 = new TestThread("窗口3");
27         h1.start();
28         h2.start();
29         h3.start();
30     }
31 
32     private int num = 5;
33 }

      在这个简单的例子中,能够很清楚的看到继承Thread实现多线程的实现已经调用,本例中运行的结果为:code

1 窗口1正在卖票  num= 5
 2 窗口1正在卖票  num= 4
 3 窗口1正在卖票  num= 3
 4 窗口1正在卖票  num= 2
 5 窗口1正在卖票  num= 1
 6 窗口2正在卖票  num= 5
 7 窗口2正在卖票  num= 4
 8 窗口2正在卖票  num= 3
 9 窗口2正在卖票  num= 2
10 窗口2正在卖票  num= 1
11 窗口3正在卖票  num= 5
12 窗口3正在卖票  num= 4
13 窗口3正在卖票  num= 3
14 窗口3正在卖票  num= 2
15 窗口3正在卖票  num= 1

      而且这个结果有必定的不可预知性,咱们不可以肯定线程之间执行的具体顺序,同时,更为重要的,经过继承Thread实现多线程不可以实现资源的共享,以购票为例子,假设票的总数为5张的话,咱们只能经过一个窗口来卖完这5张票,或者说,咱们开设了三个窗口,但这个三个窗口都有5张票,这显然和咱们的设计理念是有点差异的。因此,实现多线程的时候,我更喜欢使用实现Runnable接口的方法。对象

4、实现Runnable接口来实现多线程

       和继承Thread相似,当一个类实现Runnable接口时,在类中也必须重载run()方法,同时这个run()方法也是线程的入口,在调用的过程当中,经过调用start()方法来启动新线程,其基本框架为:

1 class 类名 implements Runnable{
 2 方法1;
 3 方法2;
 4 …
 5 public void run(){
 6 // other code…
 7 }
 8 属性1;
 9 属性2;
10 …
11  
12 }

         在调用的时候会稍微有一些区别,仍是以简单的窗口买票来举例说明:

1 class MyThread implements Runnable
 2 {
 3  
 4     private int ticket = 5;  //5张票
 5  
 6     public void run() 
 7     {
 8         for (int i=0; i<=20; i++) 
 9         {
10             if (this.ticket > 0) 
11             {
12                 System.out.println(Thread.currentThread().getName()+ "正在卖票"+this.ticket--);
13             }
14         }
15     }
16 }
17 public class TestThread {
18      
19     public static void main(String [] args) 
20     {
21         MyThread my = new MyThread();
22         new Thread(my, "1号窗口").start();
23         new Thread(my, "2号窗口").start();
24         new Thread(my, "3号窗口").start();
25     }
26 }

       程序执行的结果为:

1 1号窗口正在卖票5
2 1号窗口正在卖票4
3 1号窗口正在卖票3
4 2号窗口正在卖票2
5 1号窗口正在卖票1

       因而,咱们看到了咱们预先设定的效果,也就是说经过实现Runnable接口的方法,咱们实现的资源的共享。

5、小结

     在继承Thread类实现多线程时,咱们建立了三个不一样的对象,因此建立的三个线程其实是完成的三个不一样的任务,因此才会相互独立的完成;而经过实现Runable接口来实现多线程时,咱们只建立了一个对象,而后实例化三个不一样的线程去完成这个任务,因此至关因而共同完成任务。

     其实,其实Thread类也是实现Runnable接口的,其源代码以下:

1 class Thread implements Runnable {
2     //…
3 public void run() {
4         if (target != null) {
5              target.run();
6         }
7         }
8 }

      Thread中的run方法其实就是调用的是Runnable接口的run方法。方法是死的,人是活的,具体使用,能够根据实际状况来选择。若是一个类继承Thread,则不适合资源共享。可是若是实现了Runable接口的话,则突破了Java中单继承的限制,很容易的实现资源共享。

相关文章
相关标签/搜索