一、Java有两种方式实现多线程,第一个是继承Thread类,第二个是实现Runnable接口。他们之间的联系:

    1、Thread类实现了Runable接口。

  2、都需要重写里面Run方法。

二、实现Runnable接口相对于继承Thread类来说,有如下显著的好处:

  1、适合多个相同程序代码的线程去处理同一资源的情况,把虚拟CPU(线程)同程序的代码,数据有效的分离,较好地体现了面向对象的设计思想。

  2、可以避免由于Java的单继承特性带来的局限。我们经常碰到这样一种情况,即当我们要将已经继承了某一个类的子类放入多线程中,由于一个类不能同时有两个父类,所以不能用继承Thread类的方式,那么,这个类就只能采用实现Runnable接口的方式了。

  3、有利于程序的健壮性,代码能够被多个线程共享,代码与数据是独立的。当多个线程的执行代码来自同一个类的实例时,即称它们共享相同的代码。多个线程操作相同的数据,与它们的代码无关。当共享访问相同的对象是,即它们共享相同的数据。当线程被构造时,需要的代码和数据通过一个对象作为构造函数实参传递进去,这个对象就是一个实现了Runnable接口的类的实例。

看一下以继承Thread的卖票例子:

class MyThread extends Thread{
private int ticket = 5;
public void run(){
while(true){
System.out.println("Thread ticket = " + ticket--);
if(ticket < 0){
break;
}
}
}
}
public static void main(String[] args) {
new MyThread().start();
new MyThread().start(); }

  输出结果:

Thread ticket = 5
Thread ticket = 5
Thread ticket = 4
Thread ticket = 4
Thread ticket = 3
Thread ticket = 2
Thread ticket = 3
Thread ticket = 1
Thread ticket = 2
Thread ticket = 0
Thread ticket = 1
Thread ticket = 0

 从结果可以看出:创建了两个多线程对象,他们分别实现了买票任务; 

实现Runnable接口的卖票例子:

class MyThread2 implements Runnable{
private int ticket = 5;
public void run(){
while(true){
System.out.println("Runnable ticket = " + ticket--);
if(ticket < 0){
break;
}
}
}
} <pre name="code" class="html">public static void main(String[] args) {
MyThread2 m=new MyThread2();
  new Thread(m).start();
  new Thread(m).start(); }

输出结果:

 Runnable ticket = 5
Runnable ticket = 4
Runnable ticket = 3
Runnable ticket = 2
Runnable ticket = 1
Runnable ticket = 0

从结果可以看出虽然我们声明了两个线程,但是一共卖了6张票。他们实现了资源共享。PS:在实际开发中,一定要注意命名规范,其次上面实现Runable接口的例子由于同时操作一个资源,会出现线程不安全的情况,如果情况需要,我们需要进行同步操作。

三、线程多次调用start方法,引发的异常  

  通过调用Thread类的start()方法来启动一个线程,这时此线程是处于就绪状态,并没有运行。然后通过此Thread类调用方法run()来完成其运行操作的,这里方法run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程终止,而CPU再运行其它线程,而如果直接用Run方法,这只是调用一个方法而已,程序中依然只有主线程--这一个线程,其程序执行路径还是只有一条,这样就没有达到写线程的目的。

  一个线程对象只能调用一次start方法.从new到等待运行是单行道,所以如果你对一个已经启动的线程对象再调用一次start方法的话,会产生:IllegalThreadStateException异常.

  可以被重复调用的是run()方法。
  Thread类中run()和start()方法的区别如下:
    run()方法:在本线程内调用该Runnable对象的run()方法,可以重复多次调用;
    start()方法:启动一个线程,调用该Runnable对象的run()方法,不能多次启动一个线程;

Thread和Runnable的区别和联系、多次start一个线程会怎么样的更多相关文章

  1. Java 使用线程方式Thread和Runnable,以及Thread与Runnable的区别

    一. java中实现线程的方式有Thread和Runnable Thread: public class Thread1 extends Thread{ @Override public void r ...

  2. 三、多线程之Thread与Runnable的区别

    Thread与Runnable的区别(用三个窗口同时出售10张车票为例子) 运行代码 运行结果 分析 System.out.println("开始测试多线程");class MyT ...

  3. Java学习从菜鸟变大鸟之三 多线程中Thread 和Runnable的区别与运用

    多线程机制是java中的一个特点,掌握它对后面的知识的理解至关重要,是java工程师的必备知识,多线程指在单个程序中可以运行多个不同的线程执行的不同的任务,线程是一个程序内部的顺序控制流.进程是静态的 ...

  4. 并发编程之多线程基础-Thread和Runnable的区别及联系(二)

    上篇文章讲述了创建线程的常用方式 本篇主要分析一下Thread和Runnable两种方式创建线程的区别及联系 联系: ▶Thread类实现了Runable接口. ▶都需要重写里面Run方法. 区别: ...

  5. Thread和Runnable的区别和匿名内部类方式实现线程的创建

    如果一个类继承Thread,则不适合资源共享.但是如果实现了Runable接口的话,则很容易的实现资源共享. 总结:实现Runnable接口比继承Thread类所具有的优势: 1.适合多个相同的程序代 ...

  6. Thread 和 Runnable 的区别

    在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口: Thread类是在java.lang包中定义 的.一个类只要继承了Thread类同时覆写了本类中的run ...

  7. java线程(上)Thread和Runnable的区别

    首先讲一下进程和线程的区别: 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程. 线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈 ...

  8. Java并发实现一(并发的实现之Thread和Runnable的区别)

    package com.subject01; public class ThreadOrRunnable { public static void main(String[] args) { Syst ...

  9. Thread和Runnable的区别

    Runnable源码 Thread源码 结论 Thread实现了Runnable接口的类,使得run支持多线程. 因类的单一继承原则,推荐使用Runnable接口实现多线程

随机推荐

  1. ABP框架是怎么一回事呢?

    ABP(ASP.NET Boilerplate['bɔɪlɚplet]:样板文件),就是一套基于.Net开源框架,官方地址为:https://aspnetboilerplate.com/ , 在这个地 ...

  2. MFC原理第五讲.消息映射.以及如何添加消息

    MFC原理第五讲.消息映射.以及如何添加消息 一丶消息映射是什么 我们知道.Win32程序.都是通过消息去驱动的. 不断的在处理消息. 只要我们使用固定的宏.就可以让我们的框架知道一旦消息发生.该往哪 ...

  3. centos7安装遇到的坑

    1.安装中遇到what is the location of the gcc program on your machine 直接输入 no.意思就是跳过gcc的安装了.但是系统虽然安装了vmware ...

  4. SHELL脚本--变量(基础)

    bash&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html 变量存在于内存中.假设变量str,设置或修改变量属性时,不带$ ...

  5. Python系列:五、异常处理-技术流ken

    至今为止还没有进一步的谈论过错误信息,不过在你已经试验过的那些例子中,可能已经遇到过一些.Python 中(至少)有两种错误:语法错误和异常( syntax errors 和 exceptions ) ...

  6. [转]BTC手续费计算,如何设置手续费

    本文转自:https://blog.csdn.net/servletcome/article/details/81941334 首先BTC的交易手续费和交易金额是没有关系的.不要误认为交易的金额越大手 ...

  7. 【转载】Windows服务器修改远程桌面默认端口

    因为 windows服务器远程桌面端口默认是 3389端口,使用系统默认端口的风险很大,很容易被攻击软件扫描以及攻击,同时频繁的扫描和攻击会导致服务器的 CPU 及带宽资源耗尽,因此为了保证服务器的安 ...

  8. .NET使用ServerManager获取网站物理路径

    最近因为工作需要,用wpf做了一个辅助小工具,如下图 为了获取网站的物理路径,我分析了通过ServerManager获取到的变量,也通过百度搜索了很多,但仍然没有找到方法. 后来使用必应,在国外网站找 ...

  9. TortoiseGit为github账号添加SSH keys,解决pull总是提示输入密码的问题

    每次同步或者上传代码到githun上的代码库时,需要每次都输入用户名和密码,这时我们设置一下SSH key就可以省去这些麻烦了.若果使用TortoiseGit作为github本地管理工具,Tortoi ...

  10. log4.net 自定义日志文件名称

    插件化项目中,遇到这样一个需求,每个插件 或者每个方法 一个日志文件,方便后期错误排查 源码地址: https://github.com/xlb378917466/SharpHttpServerCas ...