java线程-Thread和Runnable的区别

进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程。

线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。

线程和进程一样分为五个阶段:创建、就绪、运行、阻塞、终止。

多进程是指操作系统能同时运行多个任务(程序)。

多线程是指在同一程序中有多个顺序流在执行

在java中要想实现多线程,有两种手段,一种是继续Thread类,另外一种是实现Runable接口。

Thread类是在java.lang包中定义的。一个类只要继承了Thread类同时覆写了本类中的run()方法就可以实现多线程操作了,但是一个类只能继承一个父类,这是此方法的局限。

一、多线程建立方式

Thread&Runnable分别模拟卖火车票

1、thread方式

class MyThread extends Thread
{
    private int ticketsCont=5; //一共有5张火车票

    private String name; //窗口, 也即是线程的名字

    public MyThread(String name){
        this.name=name;
    }

    @Override
    public void run(){

        while(ticketsCont>0){
            ticketsCont--; //如果还有票,就卖掉一张票
            System.out.println(name+"卖掉了1张票,剩余票数为:"+ticketsCont);
        }

    }
}

public class TicketsThread
{
    public static void main(String args[]){

        //创建三个线程,模拟三个窗口卖票
        MyThread mt1=new MyThread("窗口1");
        MyThread mt2=new MyThread("窗口2");
        MyThread mt3=new MyThread("窗口3");

        //启动三个线程,也即是窗口,开始卖票
        mt1.start();
        mt2.start();
        mt3.start();

    }
}

这样程序可以正常完成交互式运行。那么为啥非要使用start();方法启动多线程呢?

在JDK的安装路径下,src.zip是全部的java源程序,通过此代码找到Thread中的start()方法的定义,可以发现此方法中使用了private native void start0();其中native关键字表示可以调用操作系统的底层函数,那么这样的技术成为JNI技术(java Native Interface)。

2、Runnable方式

步骤:
     1,定义类实现Runnable接口
     2,覆盖Runnable接口中的run方法
          将线程要运行的代码存放在该run方法中
     3,通过Thread 类建立线程对象
     4,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数
          为什么要将Runnable接口中的子类对象传递给Thread的构造函数
          因为,自定义的run方法所属的对象是Runnable接口的子类对象
          所以要让线程去指定指定对象的run方法,就必须明确该run方法所属对象。
     5,调用Thread类的start方法 开启线程并调用Runnable接口子类的run方法

class MyThread2 implements Runnable
{
    private int ticketsCont=5; //一共有5张火车票

    @Override
    public void run(){

            while(true){
                 synchronized(this){
                    if(ticketsCont<=0){
                        break;
                    }
                    ticketsCont--; //如果还有票,就卖掉一张票

                    System.out.println(Thread.currentThread().getName()+"卖掉了1张票,剩余票数为:"+ticketsCont);

                    /*try{
                        Thread.sleep(50);  //通过阻塞程序来查看效果
                    }
                    catch(Exception e){
                        System.out.println(e);
                    }*/

                }
            }

    }

}

public class TicketsRunnable
{
    public static void main(String args[]){

        MyThread2 mt=new MyThread2();
        //创建三个线程来模拟三个售票窗口
        Thread th1=new Thread(mt,"窗口1");
        Thread th2=new Thread(mt,"窗口2");
        Thread th3=new Thread(mt,"窗口3");

        //启动三个线程,也即是三个窗口,开始卖票
        th1.start();
        th2.start();
        th3.start();

    }
}

但是在使用Runnable定义的子类中没有start()方法,只有Thread类中才有。此时观察Thread类,有一个构造方法:public Thread(Runnable targer)此构造方法接受Runnable的子类实例,也就是说可以通过Thread类来启动Runnable实现的多线程。(start()可以协调系统的资源):

二、总结

  • 创建:新建一个线程对象,如Thread thd=new Thread()

  • 就绪:创建了线程对象后,调用了线程的start()方法(此时线程知识进入了线程队列,等待获取CPU服务 ,具备了运行的条件,但并不一定已经开始运行了)
  • 运行:处于就绪状态的线程,一旦获取了CPU资源,便进入到运行状态,开始执行run()方法里面的逻辑
  • 终止:线程的run()方法执行完毕,或者线程调用了stop()方法,线程便进入终止状态
  • 阻塞:一个正在执行的线程在某些情况系,由于某种原因而暂时让出了CPU资源,暂停了自己的执行,便进入了阻塞状态,如调用了sleep()方法

在基于线程实现的多线程上(例子1),则总共开辟了三个窗口,在每个窗口卖了5张票,总共卖了15张票,无法实现资源共享,造成程序出错。

在基于Runnable是,利用同步共享,实现资源共享,则三个窗口总共卖了5张票。

建议使用Runnable这种方式创建线程。 程序中的同一资源指的是同一个Runnable对象。安全的卖票程序中需要加入同步synchronized。

参考文献

1、JAVA多线程Thread VS Runnable详解

2、Java中Runnable和Thread的区别

时间: 2024-10-12 14:28:07

java线程-Thread和Runnable的区别的相关文章

Java 中Thread 和Runnable的区别

转:http://blog.csdn.net/wwww1988600/article/details/7309070 在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类是在java.lang包中定义的.一个类只要继承了Thread类同时覆写了本类中的run()方法就可以实现多线程操作了,但是一个类只能继承一个父类,这是此方法的局限. 两种实现方式的区别和联系:    在程序开发中只要是多线程肯定永远以实现Runnable接口为主,因为实现

Thread 和Runnable的区别

Thread 和Runnable 的区别 Thread类 在java中可有两种方法实现度线程,一种是继承Thread类,一种是实现Runnable接口.Thread类是在java.lang包中定义的.一个类只要继承了Thread类,并覆写了本类的run()方法就可以实现多线程操作了,但是一个类只能继承一个父类,这就是此方法的局限性. 但是,此时结果很有规律,先是第一个对象执行,然后第二个对象执行,并没有相互运行.在JDK的文档中可以发现,一旦调用start()方法.下面启动start()方法启动

java 线程 --- Thread,Runnable,Callable 基础学习

java 使用 Thread 类代表线程,所有现场对象都必须是 Thread 类或者其子类的实例.每个线程的作用是完成一定的任务,实际上就是执行一段程序流.java 使用线程执行体来代表这段程序流. 1.继承Thread 类创建线程 启动多线程的步骤如下: (1)定义Thread 类的子类,并重写该类的run() 方法,该run() 方法的方法体就代表类线程需要完成的任务.因此把run() 方法称为线程执行体. (2)创建 Thread 子类的实例,即创建线程对象. (3)调用线程的star()

JAVA线程sleep和wait方法区别

一 sleep 是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复,调用sleep 不会释放对象锁.由于没有释放对象锁,所以不能调用里面的同步方法. sleep()使当前线程进入停滞状态(阻塞当前线程),让出CUP的使用.目的是不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会;sleep()是Thread类的Static(静态)的方法:因此他不能改变对象的机锁,所以当在一个Synchronized块

Thread 和 Runnable 的区别

在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口: Thread类是在java.lang包中定义 的.一个类只要继承了Thread类同时覆写了本类中的run()方法就可以实现多线程操作了, 但是一个类只能继承一个父类,这是此方法的局限. 但是,此时结果很有规律,先第一个对象执行,然后第二个对象执行,并没有相互运行.在JDK的文档中可以发现,一旦调用start()方法,则会通过JVM找到run()方法.下面启动start()方法启动线程: 这样程序可以正

Java线程Thread及其常用方法

Java SE7 API - Thread: http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#yield%28%29 一.线程的简介 当JVM启动的时候, 通常会有一个独立的非守护线程(也就是类中的main方法所在的线程).JVM会继续运行,除非发生以下情况: Runtime类的exit()方法被调用,并且安全管理者允许退出发生. 所有非守护线程都已经死了,不管是从run方法中返回的还是因为run方法中抛出了异常. 注

多线程——Thread与Runnable的区别

首先,从使用形式上,使用Runnable实现多线程更好,因为避免了单继承问题,但除了这一点之外,Thread和Runnable之间也存在一些联系.观察Thread类的定义形式: public class Threadextends Objectimplements Runnable 原来Thread类是Runnable接口的子类,那么Thread类也应该覆写了run()方法. @Override public void run() { if (target != null) { target.r

java 线程 Thread 使用介绍,包含wait(),notifyAll() 等函数使用介绍

(原创,转载请说明出处!谢谢) 目录: --线程的创建: --启动线程 --线程的调度 --Thread 类的简介 --线程的同步/异步 --wait() 和 notify(),notifyAll()方法 在讲线程之前,先说下进程. 进程是运行系统中,每个独立运行的程序.例如win7,我既用酷狗软件听歌,又玩 LOL 游戏,又上QQ,那么这就有3个进程. 线程:一个进程里面有很多线程,进程是由线程组成的,线程的结束不一定会导致进程结束,而一个进程的结束,则会连带它里面的所有线程被结束. ----

JAVA多线程Thread VS Runnable详解

要求 必备知识 本文要求基本了解JAVA编程知识. 开发环境 windows 7/EditPlus 演示地址 源文件 进程与线程 进程是程序在处理机中的一次运行.一个进程既包括其所要执行的指令,也包括了执行指令所需的系统资源,不同进程所占用的系统资源相对独立.所以进程是重量级的任务,它们之间的通信和转换都需要操作系统付出较大的开销. 线程是进程中的一个实体,是被系统独立调度和分派的基本单位.线程自己基本上不拥有系统资源,但它可以与同属一个进程的其他线程共享进程所拥有的全部资源.所以线程是轻量级的