多线程01--线程的创建和启动

来源:互联网 发布:淘宝营业额 编辑:程序博客网 时间:2024/04/29 16:38

进程和线程?
一个进程就是一个“执行中的程序”,是程序在计算机上的一次运行活动。程序要运行,系统就在内存中为该程序分配一块独立的内存空间,载入程序代码和资源进行执行。程序运行期间该内存空间不能被其他进程直接访问。系统以进程为基本单位进行系统资源的调度和分配。
线程是进程内一次具体的执行任务。程序的执行具体是通过线程来完成的,所以一个进程中至少有一个线程。回忆一下 HelloWrold 程序中main方法的执行,其实这时候,Java虚拟机会开启一个名为“main”的线程来执行程序代码。一个进程可以包含多个线程,这些线程共享数据空间和资源,但又分别拥有各自的执行堆栈和程序计数器。线程是CPU调度的基本单位。

多线程
一个进程包含了多个线程,自然就叫做多线程。拥有多个线程就可以让程序看起来可以“同时”处理多个任务,为什么是看起来呢?因为CPU也分身乏术,只能让你这个线程执行一会儿,好了你歇着,再让另一个线程执行一会儿,下次轮到你的时候你再继续执行。这里的“一会儿”实际上时间非常短,感觉上就是多个任务“同时”在执行。CPU就这样不停的切来切去…既然CPU一次也只能执行一个线程,为什么要使用多线程呢?当然是为了充分利用CPU资源。一个线程执行过程中不可能每时每刻都在占用CPU,CPU歇着的时候我们就可以让它切过来执行其他的线程。

Java中的多线程
Java中启用多线程有两种方式:①继承Thread类;②实现Runnable接口。

  • 继承Thread类
    创建一个类,继承java.lang.Thread,并覆写Thread类的run()方法,该类的实例就可以作为一个线程对象被开启。
 /** - Dog类,继承了Thread类 */class Dog extends Thread {    /*     * 覆写run()方法,定义该线程需要执行的代码     */    @Override    public void run() {        for (int i = 0; i < 10; i++) {            System.out.println(i);        }    }}

线程创建好了,怎么让它作为程序的一个独立的线程被执行呢?创建一个该类的实例,并调用start()方法,将开启一个线程,并执行线程类中覆写的run()方法。

public class ThreadDemo {    public static void main(String[] args) {        Dog dog = new Dog();        dog.start();    }}
  • 实现Runnable接口
    第二种方式,实现Runnable接口,并覆写接口中的run()方法,这是推荐的也是最常用的方式。Runnable接口定义非常简单,就只有一个抽象的run()方法。
//Runnable接口源码public interface Runnable {    public abstract void run();}
class Dog implements Runnable {    @Override    public void run() {        for (int i = 0; i < 10; i++) {            System.out.println("当前线程:" + Thread.currentThread().getName() + "---" + i);        }    }}

这时候的Dog类看起来跟线程什么的毫无关系,也没有了start()方法,怎么样开启一个新的线程呢?直接调用run()方法?想想也不行。这时候我们需要将一个Dog类的实例,作为Thread类的构造函数的参数传入,来创建一个Thread类的实例,并通过该Thread类的实例来调用start()方法从而开启线程。

public class ThreadDemo {    public static void main(String[] args) {        System.out.println("当前线程:" + Thread.currentThread().getName());        Dog dog = new Dog();        Thread thread = new Thread(dog);        thread.start();    }}

继承和实现方式的比较
继承Thread类的方式有它固有的弊端,因为Java中继承的单一性,继承了Thread类就不能继承其他类了;同时也不符合继承的语义,Dog跟Thread没有直接的父子关系,继承Thread只是为了能拥有一些功能特性。而实现Runnable接口

  • 避免了单一继承的局限性
  • 同时更符合面向对象的编程方式,即将线程对象进行单独的封装
  • 而且实现接口的方式降低了线程对象(Dog)和线程任务(run方法中的代码)的耦合性
  • 如上面所述,可以使用同一个Dog类的实例来创建并开启多个线程,非常方便的实现资源的共享。

实际上Thread类也是实现了Runnable接口。实际开发中多是使用实现Runnable接口的方式。

0 0