A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© AndyYuan 中级黑马   /  2015-8-23 12:01  /  567 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

线程和进程

进程:当一个程序进入内存运行时,即是一条进程。
进程的3个特征:
1. 独立性:进程是系统中的独立实体(包含本身拥有的资源和内存地址)在没有经过本身进程的允许下,一个进程不可以访问其他进程的地址空间。
2. 动态性:进程是一个在内存中活动的指令集。进程具有自己的生命周期。
3. 并发性:多个进程可以在单个cpu上并发执行,多个进程之间不会相互干扰。

线程:线程是进程的组成部分,可以使进程同时执行多个并发的任务。线程必须有一个父进程。

多线程的优势

进程之间不能共享内存,但线程之间共享内存很容易。
系统创建进程时需要为该线程重新分配系统资源,但线程代价小的多,因此使用多线程实现多任务比多进程的效率高
通过继承Thread类创建线程

定义Thread类的子类,并重写该类的run()方法,run()方法中就是该线程需要完成的任务。
创建Thread的实例。
调用Thread实例的start()方法。

public class FirstThread extends Thread{

    public static void main(String[] args) {
        //创建Thread实例后调用start()方法启动线程。
        new FirstThread().start();
        //启动第二个线程
        new FirstThread().start();
    }
    //重写run()方法
     public void run() {
        for(int i=0;i<50;i++){
            System.out.println(this.getName()+">"+i);
        }
     }
}
实现Runable接口创建线程类

定义实现Runable()接口的类,并重写Run()方法,在run()方法中写需要执行的任务。
创建Runable()接口类的实例,并以此实例作为Thread的target来创建Thread对象。Thread才是真正的线程对象,Thred直接执行Runable实例中的run()方法;
调用Thread的start()方法,启动线程;

public class RunnableTest implements Runnable {
    //实例属性可以在多个线程之间共享
    private int i=0 ;
    @Override
    public void run() {
         for(;i<100;i++){
             //获得线程名称时不能跟继承Thread方式一样使用this.getName();
             //因为这个类不是Thread,只是作为Thread的执行任务。
             System.out.println(Thread.currentThread().getName()+">"+i);
         }
    }public static void main(String[] args) {
        //创建实现了Runnable()接口的实例
        RunnableTest test = new RunnableTest();
        //创建线程1,test作为线程的需要任务
        new Thread(test,"thread-1").start() ;
        //创建线程2,执行的任务与线程1相同
        new Thread(test,"thread-2").start() ;
    }
}
采用Runnable接口的形式创建多个线程可以共享线程类的实例属性。因为在这种方式下程序创建的Runnable对象只是线程的Target,而多个线程共享一个Target,这样多个线程就可以共享Runnable对象的实例属性。

上面两种创建线程方式对比

采用实现Runnable()接口的方式创建多线程

线程类只是实现了Runnable()接口,还可以继承其他类;
在这种方式下,多个线程可以共享一个Target对象,实现数据共享;
不过编程相对复杂,访问当前线程时必须使用Thread.currentThread()方法;
采用继承Thread类的方式创建多线程

优势:编程简单,本身就是线程类,直接使用this 既可以访问当前线程;
缺点:由于已经继承了Thread类,就不能过在继承其他类;
线程的生命周期

线程被创建并启动后,线程并不是一启动就进入执行状态,也不是一直处于执行状态。在线程的生命周期中,线程会经过新建、就绪、运行、阻塞、死亡5种状态。当线程启动后,线程不是一直占用cpu运行,cpu不断切换选择一条线程执行。因此线程状态会多次在运行和阻塞之间切换。

新建和就绪状态

当使用new关键字创建了一个线程之后,该线程就是处于新建状态。java虚拟机会为其分配内存,并初始化成员变量。
当线程对象调用start()方法后,该线程就处于就绪状态。java虚拟机会为其创建方法调用栈和线程计数器,处于就绪状态下的线程是没有开始执行的,只是表示可以执行了。

启动线程使用Start()方法,不是run()方法。调用start()方式启动线程时,系统会将run()方法当成线程要执行的任务处理。而调用run()方法时,系统会将run()方法当成普通的方法立即执行,在run()方法反回之前,其他线程线程无法并发执行。调用run()方法后线程不再是新建状态,不能在调用start()方法

运行和阻塞状态

当处于就绪状态的线程获得了cpu,开始执行run()方法时,该线程就是运行状态。
当一个线程开始执行之后,他不可能一直是处于运行状态的。线程运行过程中会被中断,以便让其它线程进出执行状态。

线程的死亡

当run()方法执行完毕,线程正常结束
当线程抛出了一个为捕获的Exception或Error。
直接调用线程的stop()方法时。
可以调用线程对象的isAlicve()方法,来查看线程是否死亡。死亡时反回false;

死亡后的线程不能在调用start()方法了;

1 个回复

倒序浏览
风华正茂 来自手机 中级黑马 2015-8-23 12:14:47
沙发
谢谢楼主分享,楼主辛苦了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马