• 【Java多线程】两种基本实现框架


     

    Java多线程学习1——两种基本实现框架


     

    一、前言   

          当一个Java程序启动的时候,一个线程就立刻启动,改程序通常也被我们称作程序的主线程。其他所有的子线程都是由主线程产生的。主线程是程序开始就执行的,并且程序最终是以主线程的结束而结束的。

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


    二、多线程的概念 

          通常,我们接触的简单的程序都是单线程的,但是如果我们需要进行“多线操作”的话,就需要借助多线程来实现了,对于一个进程中的多个线程来说,多个线程共享进程的内存块,当有新的线程产生的时候,操作系统不分配新的内存,而是让新线程共享原有的进程块的内存。因此,线程间的通信很容易,速度也很快。不同的进程因为处于不同的内存块,因此进程之间的通信相对困难。

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


    三、继承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实现多线程的实现已经调用,本例中运行的结果为:

     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接口的方法。


    四、实现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接口的方法,我们实现的资源的共享。


    五、小结

         在继承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中单继承的限制,很容易的实现资源共享。

         多线程是Java中非常重要的部分,本文只涉及到多线程最基本的实现以及调用的部分,例如两个例子运行可能涉及到同步的问题,运行结果可能会有所出入,今后会陆续更新一些深入的东西,希望能对后来的学习者有所帮助。

    Reference:http://www.cnblogs.com/rollenholt/archive/2011/08/28/2156357.html

  • 相关阅读:
    小猪存钱罐
    SSL与HTTPS协议
    KVM之XFS磁盘扩容
    vue学习笔记(一)
    ant打包总结
    github上传代码总结
    java中map遍历的总结
    angularjs初学总结
    angularjs常用指令
    github上传代码总结
  • 原文地址:https://www.cnblogs.com/charles04/p/3917966.html
Copyright © 2020-2023  润新知