一.线程的概念模型
a.虚拟的CPU,由java.lang.Thread类封装和虚拟
b.CPU所执行的代码,传递给Thread类对象
c.CPU所处理的数据,传递给Thread类对象
二.线程体
Java的线程是通过java.lang.Thread类来实现的
每个线程都是通过某个特定Thread对象所对应的方法run()来完成其操作的,方法run()称为线程体(即线程的可执行代码)
三.多线程
四.主线程
在任何Java程序启动时,一个线程立刻运行(即main方法对应的线程),该线程通常称为程序的主线程。
主线程的特点:
a.它是产生其他子线程的线程
b.它不一定是最后完成执行的线程,子线程可能在它结束之后还在运行。
五.创建线程
有两种方法用来创建线程:
a.声明一个Thread类的子类,并覆盖run()方法
class mythread extends Thread {
public void run() {/*覆盖访方法*/}
}
b.声明一个实现Runnable接口的类,并实现run()方法
class mythread implements Runnable {
public void run() {/*覆盖访方法*/}
}
用start()方法启动线程:
Thread t1=new Thread();
t1.start();
六.Java.lang.Thread类
常用方法:
public void start():启动该线程,将导致run方法被自动调用。该方法将立即返回,新线程将运行。
public void run():必须覆盖该方法,在方法体中添加你想要在该线程中执行的代码。
public void interrupt()://用于将一个中断请求发送给线程,不安全的,Java文档中不建议用。
public final void join(long millis) throws InterruptedException:使某个线程等待指定的时间。调用某线程的该方法,将当前线程与该线程“合并”,即等待该线程结束,再恢复当前线程的运行。
public static void yield():使当前正在执行的线程临时暂停,以使其它的线程运行。
实例1:
package com.bijian.thread; //主类和线程类分开写 public class TestThread01 { public static void main(String[] args) { Thread t = new MyThread01(); t.start(); } } class MyThread01 extends Thread{ public void run() { for(int i=0;i<5;i++) { System.out.println("SubThread:" + i); } } }
运行结果:
SubThread:0 SubThread:1 SubThread:2 SubThread:3 SubThread:4
实例2:
package com.bijian.thread; //主类和线程类合并 public class MyThead02 extends Thread { public static void main(String[] args) { Thread t = Thread.currentThread(); System.out.println("主线程是:" + t); Thread ex = new MyThead02(); ex.start(); } public void run() { System.out.println("子线程是:" + this); } }运行结果:
主线程是:Thread[main,5,main] 子线程是:Thread[Thread-0,5,main]
七.Java.lang.Runnable接口
该接口只有一个方法:public void run();
实现该接口的类必须覆盖该方法。
实现了Runnable接口的类并不具有任何天生的线程处理能力,这与那些从Thread类继承的类是不同的。
为了从一个Runnable对象产生线程,必须再单独创建一个线程对象,并把Runnbale对象传递给它。
实例3:
package com.bijian.thread; //主类和线程类分开写 public class TestThread03 { public static void main(String[] args) { MyThread03 r = new MyThread03(); Thread t = new Thread(r); t.start(); } } class MyThread03 implements Runnable { public void run() { for(int i=0;i<3;i++) { System.out.println("子线程No." + i); } } }运行结果:
子线程No.0 子线程No.1 子线程No.2
实例4:
package com.bijian.thread; public class MyThread04 implements Runnable { public static void main(String[] args) { MyThread04 r = new MyThread04();//生成线程类(也就是本类)对象r Thread t = new Thread(r);//创建线程对象,把线程类对象r作为参数传递给它 t.start();//启动线程t,它会自动调用线程类对象r的run方法 } public void run() { for(int i=0;i<3;i++) { System.out.println("子线程No." + i); } } }运行结果:
子线程No.0 子线程No.1 子线程No.2
八.两种创建线程方法的比较
a.使用Runnable接口
可以将代码和数据分开,形成清晰的模型
还可以从其他类继承
保持程序风格的一致性
b.直接继承Thread类
不能再从其他类继承
编写简单,可以直接操纵线程,无需使用Thread.currentThread()
九.创建多线程
实例:
package com.bijian.thread; public class TestThread05 {//主类 public static void main(String[] args) { Runner r = new Runner();//生成线程类对象r Thread t1 = new Thread(r);//创建线程对象t1 Thread t2 = new Thread(r);//创建线程对象t2 t1.start();//启动线程t1 t2.start();//启动线程t2 } } class Runner implements Runnable {//线程类 public void run() { for(int i=0;i<3;i++) { System.out.println("No." + i); } } }
运行结果:
No.0 No.1 No.2 No.0 No.1 No.2
十.多线程共享数据和代码
对上例进行分析,可以得到下表:
线程 |
虚拟CPU |
代码 |
数据 |
t1 |
Thread类对象t1 |
Runner类中的run方法 |
Runner类型对象r |
t2 |
Thread类对象t2 |
Runner类中的run方法 |
Runner类型对象r |