[ 转载 ] Java基础14--创建线程的两个方法
http://www.cnblogs.com/whgw/archive/2011/10/03/2198506.html
Java提供了线程类Thread来创建多线程的程序。其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象。每个Thread对象描述了一个单独的线程。要产生一个线程,有两种方法:
◆需要从Java.lang.Thread类派生一个新的线程类,重载它的run()方法;
◆实现Runnalbe接口,重载Runnalbe接口中的run()方法。
为什么Java要提供两种方法来创建线程呢?它们都有哪些区别?相比而言,哪一种方法更好呢?
在Java中,类仅支持单继承,也就是说,当定义一个新的类的时候,它只能扩展一个外部类.这样,如果创建自定义线程类的时候是通过扩展 Thread类的方法来实现的,那么这个自定义类就不能再去扩展其他的类,也就无法实现更加复杂的功能。因此,如果自定义类必须扩展其他的类,那么就可以使用实现Runnable接口的方法来定义该类为线程类,这样就可以避免Java单继承所带来的局限性。
还有一点最重要的就是使用实现Runnable接口的方式创建的线程可以处理同一资源,从而实现资源的共享.
(1)通过扩展Thread类来创建多线程
假设一个影院有三个售票口,分别用于向儿童、成人和老人售票。影院为每个窗口放有100张电影票,分别是儿童票、成人票和老人票。三个窗口需要同时卖票,而现在只有一个售票员,这个售票员就相当于一个CPU,三个窗口就相当于三个线程。通过程序来看一看是如何创建这三个线程的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public class MutliThreadDemo { public static void main(String [] args){ MutliThread m1= new MutliThread( "Window 1" ); MutliThread m2= new MutliThread( "Window 2" ); MutliThread m3= new MutliThread( "Window 3" ); m1.start(); m2.start(); m3.start(); } } class MutliThread extends Thread{ private int ticket= 100 ; //每个线程都拥有100张票 MutliThread(String name){ super (name); //调用父类带参数的构造方法 } public void run(){ while (ticket> 0 ){ System.out.println(ticket--+ " is saled by " +Thread.currentThread().getName()); } } } |
程序中定义一个线程类,它扩展了Thread类。利用扩展的线程类在MutliThreadDemo类的主方法中创建了三个线程对象,并通过start()方法分别将它们启动。
从结果可以看到,每个线程分别对应100张电影票,之间并无任何关系,这就说明每个线程之间是平等的,没有优先级关系,因此都有机会得到CPU的处理。但是结果显示这三个线程并不是依次交替执行,而是在三个线程同时被执行的情况下,有的线程被分配时间片的机会多,票被提前卖完,而有的线程被分配时间片的机会比较少,票迟一些卖完。
可见,利用扩展Thread类创建的多个线程,虽然执行的是相同的代码,但彼此相互独立,且各自拥有自己的资源,互不干扰。
(2)通过实现Runnable接口来创建多线程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
public class MutliThreadDemo2 { public static void main(String [] args){ MutliThread m1= new MutliThread( "Window 1" ); MutliThread m2= new MutliThread( "Window 2" ); MutliThread m3= new MutliThread( "Window 3" ); Thread t1= new Thread(m1); Thread t2= new Thread(m2); Thread t3= new Thread(m3); t1.start(); t2.start(); t3.start(); } } class MutliThread implements Runnable{ private int ticket= 100 ; //每个线程都拥有100张票 private String name; MutliThread(String name){ this .name=name; } public void run(){ while (ticket> 0 ){ System.out.println(ticket--+ " is saled by " +name); } } } |
由于这三个线程也是彼此独立,各自拥有自己的资源,即100张电影票,因此程序输出的结果和(1)结果大同小异。均是各自线程对自己的100张票进行单独的处理,互不影响。
可见,只要现实的情况要求保证新建线程彼此相互独立,各自拥有资源,且互不干扰,采用哪个方式来创建多线程都是可以的。因为这两种方式创建的多线程程序能够实现相同的功能。
由于这三个线程也是彼此独立,各自拥有自己的资源,即100张电影票,因此程序输出的结果和例4.2.1的结果大同小异。均是各自线程对自己的100张票进行单独的处理,互不影响。
可见,只要现实的情况要求保证新建线程彼此相互独立,各自拥有资源,且互不干扰,采用哪个方式来创建多线程都是可以的。因为这两种方式创建的多线程程序能够实现相同的功能。
(3)通过实现Runnable接口来实现线程间的资源共享
现实中也存在这样的情况,比如模拟一个火车站的售票系统,假如当日从A地发往B地的火车票只有100张,且允许所有窗口卖这100张票,那么每一个窗口也相当于一个线程,但是这时和前面的例子不同之处就在于所有线程处理的资源是同一个资源,即100张车票。如果还用前面的方式来创建线程显然是无法实现的,这种情况该怎样处理呢?看下面这个程序,程序代码如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public class MutliThreadDemo3 { public static void main(String [] args){ MutliThread m= new MutliThread(); Thread t1= new Thread(m, "Window 1" ); Thread t2= new Thread(m, "Window 2" ); Thread t3= new Thread(m, "Window 3" ); t1.start(); t2.start(); t3.start(); } } class MutliThread implements Runnable{ private int ticket= 100 ; //每个线程都拥有100张票 public void run(){ while (ticket> 0 ){ System.out.println(ticket--+ " is saled by " +Thread.currentThread().getName()); } } } |
结果正如前面分析的那样,程序在内存中仅创建了一个资源,而新建的三个线程都是基于访问这同一资源的,并且由于每个线程上所运行的是相同的代码,因此它们执行的功能也是相同的。
可见,如果现实问题中要求必须创建多个线程来执行同一任务,而且这多个线程之间还将共享同一个资源,那么就可以使用实现Runnable接口的方式来创建多线程程序。而这一功能通过扩展Thread类是无法实现的,读者想想看,为什么?
实现Runnable接口相对于扩展Thread类来说,具有无可比拟的优势。这种方式不仅有利于程序的健壮性,使代码能够被多个线程共享,而且代码和数据资源相对独立,从而特别适合多个具有相同代码的线程去处理同一资源的情况。这样一来,线程、代码和数据资源三者有效分离,很好地体现了面向对象程序设计的思想。因此,几乎所有的多线程程序都是通过实现Runnable接口的方式来完成的。
[ 转载 ] Java基础14--创建线程的两个方法的更多相关文章
- Java 创建线程的两种方法
Java提供了线程类Thread来创建多线程的程序.其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象.每个Thread对象描述了一个单独的线程.要产生一个线 ...
- Java创建线程的两个方法
Java提供了线程类Thread来创建多线程的程序.其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象.每个Thread对象描述了一个单独的线程.要产生一个线 ...
- Java创建线程的两种方法
大多数情况,通过实例化一个Thread对象来创建一个线程.Java定义了两种方式: 实现Runnable 接口: 可以继承Thread类. 下面的两小节依次介绍了每一种方式. 实现Runnable接口 ...
- Java线程(一)——创建线程的两种方法
Thread 和 Runnable Java程序是通过线程执行的,线程在程序中具有独立的执行路径.当多条线程执行时,它们之间的路径可以不同,例如,一条线程可能在执行switch的一个case语句,另一 ...
- Java多线程——之一创建线程的四种方法
1.实现Runnable接口,重载run(),无返回值 package thread; public class ThreadRunnable implements Runnable { public ...
- 进程和创建线程的两种方法(threading.Thread)
进程 如QQ 要以一个整体的形式暴露给操作系统管理,里面包含对各种资源的调用,内存的管理, 网络接口的调用等,进程就是各种资源管理的集合 线程:是操作系统最小的调度单位,是一串指令的结合 进程 要操作 ...
- JAVA·多线程:创建线程的两种方式
1.–扩展java.lang.Thread类 package multiThread; public class Thread02extThread { public static void main ...
- [ 转载 ] Java基础10--关于Object类下所有方法的简单解析
关于Object类下所有方法的简单解析 类Object是类层次结构的根类,是每一个类的父类,所有的对象包括数组,String,Integer等包装类,所以了解Object是很有必要的,话不多说,我们直 ...
- Java并发基础01. 传统线程技术中创建线程的两种方式
传统的线程技术中有两种创建线程的方式:一是继承Thread类,并重写run()方法:二是实现Runnable接口,覆盖接口中的run()方法,并把Runnable接口的实现扔给Thread.这两种方式 ...
随机推荐
- Nagios Openstack Plugin
Some simple example for checking Openstack services check nova service list #!/bin/sh export OS_PROJ ...
- 读书笔记 effective c++ Item 19 像设计类型(type)一样设计类
1. 你需要重视类的设计 c++同其他面向对象编程语言一样,定义了一个新的类就相当于定义了一个新的类型(type),因此作为一个c++开发人员,大量时间会被花费在扩张你的类型系统上面.这意味着你不仅仅 ...
- 002_安装第三方APP好的站点及解除安全与隐私限制
一.解除安全与隐私限制的任何来源. http://bbs.feng.com/read-htm-tid-10714286.html 接下来,我们就打开终端,然后输入以下命令: sudo spctl ...
- linux系统时钟和硬件时钟不一致
在做DB2 集群复制的时候要求两台主机时间相互一致. 但是在一台主机上系统时间和硬件时间相差12个小时左右:手动同步后,重启后又相差12个小时左右. 为什么会是这样的,先介绍下系统时钟和硬件时钟的区别 ...
- java中Cookie使用问题(message:invalid character [32] was present in the Cookie value)
1. 问题描述 Servlet中执行下面一段代码: public void doGet(HttpServletRequest request, HttpServletResponse response ...
- SQLAlchemy-对象关系教程ORM-create
ORM是建立在SQL语言构造器之上的工具集,用于将Python对象映射到数据库的行,提供了一系列接口用于从数据库中存取对象(行).在ORM 工作时,在底层调用SQL语言构造器的API,这些通用的操作有 ...
- 正则表达式之你不知道的replace
我们都知道js内置类String提供了一个replace方法,可以把指定字符串替换为另一个字符串,他的基础用法如下: var str="hello world"; var str= ...
- 序列化 json和pickle
序列化 1. 什么叫序列化 将原本的字典.列表等内容转换成一个字符串的过程就叫做序列化. 2. json dumps loads 一般对字典和列表序列化 dump load 一般对 ...
- JAVA复习笔记之多线程并发
前言:多线程并发编程是Java编程中重要的一块内容,也是面试重点覆盖区域,还是值得深入研究一下 概念: 1 线程:进程中负责程序执行的执行单元线程本身依靠程序进行运行线程是程序中的顺序控制流,只能使用 ...
- linux 系统网卡无法识别,缺少驱动
#linux网卡驱动安装# Linux设备加载 #lsmod Module Size Used by e1000e 查看硬件设备 ls /usr/share/hwdata 查看pci网卡设备 lspc ...