一.程序,进程,线程
(1)程序(program)是为完成特定任务、用某种语言编写的一组指令的集合。即指一
段静态的代码.
(2) 进程((process)就是正在执行的程序,从Windows角度讲,进程是操作系统进行
资源 分配 的最小单位.
(3)线程(thread)进程可进一步细化为线程,是一个进程内部的最小执行单元,是操
作系统进行任务调度的最小单元,隶属于进程.
二.线程和进程的关系
(1)一个进程可以包含多个线程,一个线程只能属于一个进程,线程不能脱离进程
而独立运行;
(2)每一个进程至少包含一个线程(称为主线程);在主线程中开始执行程序, java
程序的入口main()方法就是在主线程中被执行的。
(3)在主线程中可以创建并启动其它的线程;
(4) 一个进程内的所有线程共享该进程的内存资源。
三.创建线程
继承Thread类的方式
● 在Java中要实现线程,最简单的方式就是扩展Thread类,重写其中的run方法,方法原型如下:
● Thread类中的run方法本身并不执行任何操作,如果我们重写了run方法,当线程启动时,它将执行
run方法。
调用:
MyThread thread = new MyThread();
thread.start();
package Thread.Demo;
public class Theard {
public static void main(String[] args) {
RunTask runTask = new RunTask();
Thread thread = new Thread(runTask);
thread.start();
System.out.println();
}
}
package Thread.Demo;
public class RunTask extends Thread {
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("runTask"+i);//
}
}
}
实现Runnable接口的方式
● java.lang.Runnable接口中仅仅只有一个抽象方法:
● 也可以通过实现Runnable接口的方式来实现线程,只需要实现其中的run方法即
可;
● Runnable接口的存在主要是为了解决Java中不允许多继承的问题。
package Thread.Demo3;
public class RunTask implements Runnable{
@Override
public void run() {
Thread.currentThread().setName("程序一");
Thread.currentThread().setPriority(10);
for(int i=0;i<10000;i++) {
if (i % 10 == 0) {
Thread.yield();
}
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
public class Main {
public static void main(String[] args) {
RunTask runTask=new RunTask();
Thread thread=new Thread(runTask);
//thread.start();
System.out.println(Thread.currentThread().getPriority());
//for(int i=0;i<10000;i++) {System.out.println(Thread.currentThread().getName() + ":" + i);}
}
}
继承方式和实现方式的联系与区别
【区别】
继承Thread: 线程代码存放Thread子类run方法中。
实现Runnable:线程代码存在接口的子类的run方法。
【实现Runnable的好处】
1)避免了单继承的局限性
2)多个线程可以共享同一个接口实现类的对象,非常适合多个相同线程来处
理同一份资源。
四.常用方法
void start() 启动线程
final String getName() 返回线程的名称
final void setPriority(int newPriority) 设置线程的优先级
final int getPriority() 返回线程的优先级
final void join() 等待线程终止
static Thread currentThread() 返回对当前正在执行的线程对象的引用,
static void sleep(long millis)让当前正在执行的线程休眠(暂停执行)
休眠时间由millis(毫秒)指定
yield() 线程让步
五.线程优先级
优先级较高的线程有更多获得CPU的机会,反之亦然;
优先级用整数表示,取值范围是1~10,一般情况下,线程的默认优先级
都是5,但是也可以通过setPriority和getPriority方法来设置或返回优
先级;
线程优先级
调度策略
时间片
抢占式:高优先级的线程抢占CPU
Thread类有如下3个静态常量来表示优先级
MAX_PRIORITY:取值为10,表示最高优先级。
MIN_PRIORITY:取值为1,表示最底优先级。
NORM_PRIORITY:取值为5,表示默认的优先
六.线程状态
线程的生命周期
新建:当一个Thread类或其子类的对象被声明并创建时,新生的线程对
象处于新建状态
就绪:处于新建状态的线程被start()后,将进入线程队列等待CPU时
间片,此时它已具备了运行的条件,只是没分配到CPU资源
运行:当就绪的线程被调度并获得CPU资源时,便进入运行状态,run
()方法定义了线程的操作和功能
阻塞:在某种特殊情况下,被人为挂起或执行输入输出操作时,让出
CPU并临时中止自己的执行,进入阻塞状态
死亡:线程完成了它的全部工作或线程被提前强制性地中止或出现异常
导致结束
七.守护线程
Java中的线程分为两类:用户线程和守护线程
任何一个守护线程都是整个JVM中所有非守护线程的保姆,只要当前JVM实例中尚存在
任何一个非守护线程没有结束,守护线程就全部工作;
只有当最后一个非守护线程结束时,守护线程随着JVM一同结束工作。
守护线程的作用是为其他线程的运行提供便利服务,守护线程最典型的应用就是 GC
(垃圾回收器),它就是一个很称职的守护者。
八.多线程
优点:(1)提高程序的响应.
(2) 提高CPU的利用率.
(3)改善程序结构,将复杂任务分为多个线程,独立运行.
缺点:(1)线程也是程序,所以线程需要占用内存,线程越多占用内存也越多;
(2)多线程需要协调和管理,所以需要CPU时间跟踪线程;
(3)线程之间对共享资源的访问会相互影响;