目录
一、进程与线程
进程:应用程序执行的过程,是操作系统进行资源分配和调度的一个独立单位,进程一般由程序,数据集合和进程控制块三部分组成。程序用于描述进程要完成的功能,是控制进程执行的指令集;数据集合是程序在执行时所需要的数据和工作区;程序控制块包含进程的描述信息和控制信息是进程存在的唯一标志。
线程:一个进程在执行中可以产生多个线程,简单说一个线程就像是运行在进程中的“小进程”。各个线程之间共享程序的内存空间(也就是所在进程的内存空间)。
优点:多线程编程可以充分利用CPU的资源。
工作原理:JVM虚拟机负责管理这些线程,这些线程将被轮流执行,JVM虚拟机将快速切换一个线程到另一个线程, 使得每个线程都有机会使用CPU资源,给出一个同步执行的感觉。
二、实现线程的两种方法
A、采用继承 Thread 类方法。
B、采用实现Runnable 接口的方法。
线程的生命周期:4种状态
- 1、创建线程(以上两种方法),都要创建新类并重写实现run()方法(run方法规定了线程的具体工作内容)。
- 2、运行—使用创建的新类实例化一个线程对象,调用start()方法(从父类继承的方法)通知JVM,JVM就会知道又有一个新线程在排队等候了。当JVM把CPU使用权切换给某一个线程时,立刻执行run()方法里面的具体内容。
- 3、中断—意思是该线程让出CPU的使用权,回到线程队列中排队等候。可以使用类方法sleep()让该线程休眠指定时间。
- 4、死亡—该线程执行完了run()方法里面的全部代码。
方法A:采用继承 Thread 类方法。
class MyThread extends Thread{ //必须为Thread类的子类
@Override
public void run() {
while (true) {
System.out.println("hello,word");
}// 需要多线程操作的代码 放入重写的 run方法中
}
}
class TestClass{
MyThread myth=new MyThread();
myth.start(); //调用 Thread父类的 start方法,将run方法中的任务分配给CPU核运行
}
方法B:采用实现Runnable 接口的方法。
注意:实现接口Runnable的类没有 start方法,因此需要用Thread类进行包装加强。
class MyThread implements Runnable{
@Override
public void run() {
while(true){} // 需要多线程操作的代码 放入重写的 run方法中
}
}
class TestClass{
MyThread myth = new MyThread();//实现接口的类没有 start方法,因此需要用Thread类进行包装加强
Thread th = new Thread(myth);//创建Thread类的一个对象,并把实现接口的myth对象作为参数
th.start(); //调用 Thread类对象的start方法,将对象myth的run方法中的任务分配给CPU核运行
}
Thread的构造方法是:Thread(Runnable target),参数是一个Runnable类型的接口。
理解 run() 方法 和 start( )方法 : run() -- 定义多线程运行的代码 ; start()---开启线程,分配CPU资 源。
识别当前线程是哪一个的方法 :
- 给名字——线程对象.setName()
- 获取名字 ——Thread.currentThread().getName()
三、课堂练习 —龟兔赛跑
题目要求:
- 1、兔子每秒跑5米,但是每10米要休息2秒;
- 2、乌龟每秒钟4米,不休息 ;
- 3、谁先到达 终点,比赛结束;
- 4、跑道长度100米
方案一;采用接口Runnable的方式
import java.util.logging.Level;
import java.util.logging.Logger;
public class Race implements Runnable {
private int speed;//每秒多少米?速度
private int sleep;//每隔多少秒休息,若不休息 为 -1 休息间隔
private int sleepTime;//每次休息多少秒 休息时长
private int len;//跑道长度
//构造方法
public Race(int speed, int sleep, int sleepTime, int len) {
this.speed = speed;
this.sleep = sleep;
this.sleepTime = sleepTime;
this.len = len;
}
@Override
public void run() {
int dis=0;//已经跑的路程(米)
while (true) {
len -= speed;//总长度
dis += speed;
if (len <= 0) {
System.out.println("#====="+Thread.currentThread().getName()+
"到达终点=========");//利用类方法 Thread.currentThread() 获取当前正在运行的线程对象。
break;
}
else {
System.out.println(Thread.currentThread().getName()+"离终点还剩"+len+"米");
}
//添加休息
if(sleep>-1 && dis % sleep==0){
System.out.println("#--- "+Thread.currentThread().getName()+ "开始睡觉!=========");
Thread.sleep(sleepTime*1000);
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(Race.class.getName()).log(Level.SEVERE, null,ex);
}
}
}
//测试类
public class TestClass {
public static void main(String[] args) {
final int distance = 100;
//兔子
Race rabbit = new Race(5, 10, 2, distance);
Thread thR = new Thread(rabbit);
thR.setName("兔子"); //采用 setName 给线程一个名字
thR.start();
//乌龟
Race tortoise = new Race(4, -1, -1, distance);
Thread thT = new Thread(tortoise);
thT.setName("乌龟");//采用 setName 给线程一个名字
thT.start();
}
}