【多线程】Java线程模型

来源:互联网 发布:java基础入门课后答案 编辑:程序博客网 时间:2024/05/16 00:26

1. 相关概念:

  • 程序:安装在磁盘上的一段指令的集合,是静态的。
  • 进程:是运行中的程序,是动态的。每个进程有独立的资源空间。
  • 线程:又称轻量级进程,是程序执行流的最小单元,是程序中单一的顺序控制流程。线程是进程中的一个实体,是被系统独立调度和分派的基本单位。
  • 多线程:在单个程序中,可以同时运行多个不同的线程执行不同的任务

线程才是真正干活的,进程无非是分配了资源的空间,一个进程中有多个线程,线程共享了进程的资源空间。所以当一个程序开始运行,至少已经开启了一个进程。

2. 线程模型:

2.1.通过继承Thread类创建线程

  • 普通Java类如果继承了Thread类就成了一个线程类,并可以通过该类的start方法启动线程,执行线程代码。
  • Thread类的子类可以直接实例化,但是在子类中必须覆盖run方法才能真正运行线程代码
class PrimeThread extends Thread {        long minPrime;        PrimeThread(long minPrime) {            this.minPrime = minPrime;        }        //在子类中重写了thread类的run方法        public void run() {            // compute primes larger than minPrime              . . .        }    }
//实例化线程类的子类PrimeThread p = new PrimeThread(143);    p.start();

2.2 通过实现Runnable接口创建线程

实现Runnable接口的类必须借助Thread类才能创建线程。通过Runnable接口创建线程分为两步;

  • 创建实现Runnable接口的类的实例;
  • 创建一个Thread类对象,将第一步实例化得到的Runnable对象作为参数传入Thread类的构造方法;
  • 通过Thread类的start方法启动线程
//创建实现Runnable接口的类的实例class PrimeRun implements Runnable {        long minPrime;        PrimeRun(long minPrime) {            this.minPrime = minPrime;        }        public void run() {            // compute primes larger than minPrime              . . .        }    }
PrimeRun p = new PrimeRun(143);    //将实例化得到的Runnable对象作为参数传入Thread类的构造方法;    new Thread(p).start();

API:
http://tool.oschina.net/apidocs/apidoc?api=jdk-zh

3. Thread类常用方法:

static Thread currenThread():返回对当前正在执行的线程对象的引用。
long getId():返回该线程的标识符。
String getName():返回该线程的名称。
int getPriority(): 返回线程的优先级。
Thread.State getState():返回该线程的状态。
void interrupt():中断线程。
boolean isAlive():测试线程是否处于活动状态。
void join():等待该线程终止
static void sleep(long millis):线程休眠
void start():使该线程开始执行;Java 虚拟机调用该线程的 run 方法。

4. Code Demo:

4.1 继承Thread类创建多个线程

public class ThreadDemo {     public static void main(String[] args) {          //产生一个线程类对象          HelloThread h1=new HelloThread();          //自定义线程名称setName          h1.setName("线程1");          //调用线程类实例的start方法,启动线程,就会调用线程实例的run方法执行          h1.start();          //一个线程类可以创建多个线程实例          //Thread(String name)方法在实例化线程的同时指定了线程名称          HelloThread h2=new HelloThread("线程2");          h2.start();     }}class HelloThread extends Thread{     //线程初始化     public HelloThread() {     }     //带参数的线程初始化     public HelloThread(String name) {          super(name);     }     //重写父类的run方法     @Override     public void run() {          for(int i=0;i<5;i++){              //获取线程的名称getName              System.out.println(this.getName()+"--"+i);          }     }}

4.2 实现Runnable接口创建多个线程

public class HelloRunnableDemo {     public static void main(String[] args) {          HelloRunnable hr=new HelloRunnable();          Thread t1=new Thread(hr,"线程A");          t1.start();          Thread t2=new Thread(hr,"线程B");          t2.start();     }}class HelloRunnable implements Runnable{     @Override     public void run() {          for(int i=0;i<5;i++){              //获取线程的名称getName               System.out.println(Thread.currentThread().getName()+i);          }     }}

一般情况下,使用第二种方法,即实现Runnable接口来创建线程,主要是因为:

  1. 避免单继承的局限,一个类可以实现多个接口,但只能继承一个类
  2. 适合资源的共享

我们用一个多线程买票的例子说明二者的区别:

用继承Thread的方法创建两个线程对象,s1和s2,各自不能共享数据,实际上是每个线程都有5张票。类似于“计划经济”,每个线程有固定的指标,彼此互不影响。

public class SharedDataThreadDemo {     public static void main(String[] args) {          TicketThread s1=new TicketThread("窗口1:");          s1.start();          TicketThread s2=new TicketThread("窗口2:");          s2.start();     }}class TicketThread extends Thread{     private int tickets=5;     public TicketThread(String name){          super(name);     }     @Override     public void run() {          while(true){               System.out.println(this.getName()+(tickets--));              if(tickets<1){                   break;              }          }     }}

通过实现Runnable接口,只产生了一个对象,但是可以创建任意多个线程,这些线程都是共享对象的属性的。
也就是说所有窗口提供的票数是固定的,不管从哪里买,票数都会发生变化

public class SharedDataThreadDemo {     public static void main(String[] args) {/*             TicketRunnable runnable=new TicketRunnable();          Thread t1=new Thread(runnable,"窗口1");          t1.start();          Thread t2=new Thread(runnable,"窗口2");          t2.start();     }}class TicketRunnable implements Runnable{     private int tickets=5;     @Override     public void run() {          while(true){               System.out.println(Thread.currentThread().getName()+":"+(tickets--));              if(tickets<1){                   break;              }          }     }}
0 0
原创粉丝点击