【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

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

时间: 2024-10-26 19:05:08

【Java多线程】两种基本实现框架的相关文章

java多线程 —— 两种实际应用场景模拟

java多线程-两种实际应用场景模拟 转自 薛定谔的猫 (一) 先说说第一个,模拟对信息的发送和接收.场景是这样的: 就像笔者之前做的消息的发送,一个是服务器,一个是客户端.发送的话,要保证信息100%的发送给客户端,那么发给客户端之后,客户端返回一个消息告诉服务器,已经收到.当服务器一直没有收到客户端返回的消息,那么服务器会一直发送这个信息,直到客户端发送回确认信息,这时候再删除重复发送的这个信息. 为了模拟这个场景,这里写两个线程,一个是发送,一个是接收,把发送的信息,要保存到线程安全的对象

Java中有两种实现多线程的方式以及两种方式之间的区别

网上流传很广的是一个网上售票系统讲解.转发过来.已经不知道原文到底是出自哪里了. Java中有两种实现多线程的方式.一是直接继承Thread类,二是实现Runnable接口.那么这两种实现多线程的方式在应用上有什么区别呢? 为了回答这个问题,我们可以通过编写一段代码来进行分析.我们用代码来模拟铁路售票系统,实现通过四个售票点发售某日某次列车的100张车票,一个售票点用一个线程表示. 我们首先这样编写这个程序: Java代码    class ThreadTest extends Thread{

Java中两种实现多线程方式的对比分析

本文转载自:http://www.linuxidc.com/Linux/2013-12/93690.htm#0-tsina-1-14812-397232819ff9a47a7b7e80a40613cfe1 Java中有两种实现多线程的方式.一是直接继承Thread类,二是实现Runnable接口.那么这两种实现多线程的方式在应用上有什么区别呢? 为了回答这个问题,我们可以通过编写一段代码来进行分析.我们用代码来模拟铁路售票系统,实现通过四个售票点发售某日某次列车的100张车票,一个售票点用一个线

java String 两种不同的赋值 比较

原文http://blog.163.com/[email protected]/blog/static/1271436362012101214031911/ 在此感谢博主写出这么优秀的文章. 首先明确一点,String是一个类.下面我们主要讨论两个问题  a) String类的对象的两种赋值方式  b) 为什么String类的对象可以直接赋值  a) 1 类似普通对象,通过new创建字符串对象.String str = new String("Hello"); 内存图如下图所示,系统会

多线程两种实现方式的区别

请解释Thread类与Runnable接口实现多线程的区别?(请解释多线程两种实现方式的区别?) 1. Thread类时Runnable接口的子类,使用Runnable接口实现多线程可以避免单继承局限!2. Runnable接口实现的多线程可以比Thread类实现的多线程更加清楚的描述数据共享的概念! 请写出多线程两种实现操作?(写出Thread类继承的方式和Runnable接口实现的方式代码!) 实现Thread类: 类似于代理设计模式! class MyThread extends Thre

JAVA 中两种判断输入的是否是数字的方法__正则化_

JAVA 中两种判断输入的是否是数字的方法 package t0806; import java.io.*; import java.util.regex.*; public class zhengzehua_test { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub try { System.out.println("请输入第一个数字:"

java中两种添加监听器的策略

/*第一种:将事件的处理委托给其他对象,下面的例子是委托给了MyListener(implements ActionListener)*/ 1 import java.applet.Applet; 2 import java.awt.event.*; 3 import java.awt.*; 4 public class ChangeColor extends Applet{//Applet的默认布局为FlowLayout方式 5 Color myColor; 6 String str; 7 B

Java中两种动态代理的实现

本文介绍了java中两种动态代理的实现方法,Spring的动态代理也是基于这两种方法的.直接附上源码: 1.JDK实现 使用JDK实现动态代理必须使用接口 接口Work.java public interface Work { public void work(); } 实现类WorkImpl.java public class WorkImpl implements Work { @Override public void work() { System.out.println("我在工作&q

JAVA学习篇--JAVA的两种编程模式对比

在Drp项目中,讲解了两种编程模式Model 1和Model2,下面是对这两种模式的简单理解,以及由于Model2是基于MVC架构的模式,就将我们易混淆的MVC与我们之前学的三层架构进行对比学习一下. Model1 所谓Model1就是JSP大行其道的时代,在Model1模式下,整个Web应用几乎全部由JSP页面组成,JSP页面接收处理客户端请求,对请求处理后直接做出响应.用少量的JavaBean来处理数据库连接.数据库访问等操作. 代码示例:修改用户信息 主页面的js跳转: function