文章目录
- 1. 进程和线程
- 2. 多线程实现方式
- 3. 设置和获取线程名称
- 4. 线程优先级
- 5. 线程控制
- 6. 线程的生命周期
1. 进程和线程
1. 进程:是正在运行的程序,是系统进行资源分配和调用的基本单位。每一个进程都有它自己的内存空间和系统资源。
2. 线程:是进程中的单个顺序控制流,是一条执行路径。
- 单线程:一个进程如果只有一条执行路径,则称为单线程程序。
- 多线程:一个进程如果有多条执行路径,则称为多线程程序。
2. 多线程实现方式
1. 创建一个新的执行线程有两种方法,一个是将一个类声明为一个Thread
的子类。这个子类应该重写Thread
类的run()
方法,然后可以分配并启动子类的实例。
2. 具体继承Thread
类:(1) 定义一个MyThread
类继承Thread
类。 (2) 在MyThread
类中重写run()
方法。 (3) 创建MyThread
类的对象。 (4) 启动线程。
public class MyThread extends Thread{
@Override
public void run() {
for(int i=0;i<200;i++)
{
System.out.println(i);
}
}
}
public class MyThreadDemo {
public static void main(String[] args) {
MyThread my1=new MyThread();
MyThread my2=new MyThread();
my1.start();
my2.start();
}
}
3. 为什么要重写run()
方法?因为run()
方法是用来封装被线程执行的代码。
4. run()
方法和start()
方法的区别?run()
:封装线程执行的代码,直接调用,相当于普通方法的调用。start()
:启动线程,然后由JVM调用此线程的run()
方法。
3. 设置和获取线程名称
1. 在上面的例子中用getName()
来获取线程名字。这里无参构造方法给出了默认名称。也可以通过setName()
方法重新命名线程名称。
public class MyThread extends Thread{
@Override
public void run() {
for(int i=0;i<200;i++)
{
System.out.println(getName()+" "+i);
}
}
}
public class MyThreadDemo {
public static void main(String[] args) {
MyThread my1=new MyThread();
MyThread my2=new MyThread();
my1.setName("线程1");
my2.setName("线程2");
my1.start();
my2.start();
}
}
2. 用带参构造方法设置线程名称。这个时候子类应该继承父类的构造方法。
public class MyThread extends Thread{
public MyThread(){}
public MyThread(String name){
super(name);
}
@Override
public void run() {
for(int i=0;i<200;i++)
{
System.out.println(getName()+" "+i);
}
}
}
public class MyThreadDemo {
public static void main(String[] args) {
MyThread my1=new MyThread("线程1");
MyThread my2=new MyThread("线程2");
my1.start();
my2.start();
}
}
3. currentThread()
:返回对当前正在执行的线程对象的引用。
public class MyThreadDemo {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName());
//输出:main
}
}
4. 线程优先级
1. 线程调度有两种模型:(1) 分时调度模型:所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间片。 (2) 抢占式调度模型:优先让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的CPU时间片相对多一些。
2. Java使用的是抢占式调度模型。
3. 假设计算机只有一个CPU,那么计算机在某一个时刻只能执行一条指令,线程只有得到CPU时间片,也就是使用权,才可以执行指令。所以说多线程程序的执行是有随机性的,因为谁抢到CPU的使用权是不一定的。
4. Thread类中设置和获取线程优先级的方法:(1) public final int getPriority()
:返回此线程的优先级。 (2) public final void setPriority(int newPriority)
:更改此线程的优先级。
5. 线程默认优先级是5,线程优先级范围是1-10。注意:线程优先级高仅仅表示线程获取的CPU时间片的几率高,并不代表一定先执行完它。(要实现先执行完,得用join()
)
public class MyThread extends Thread{
public MyThread(){}
public MyThread(String name){
super(name);
}
@Override
public void run() {
for(int i=0;i<200;i++)
{
System.out.println(getName()+" "+i);
}
}
}
public class MyThreadDemo {
public static void main(String[] args) {
//输出结果都是5,所以线程优先级默认是5
MyThread my1=new MyThread("线程1");
MyThread my2=new MyThread("线程2");
System.out.println(my1.getPriority());
System.out.println(my2.getPriority());
// my1.start();
// my2.start();
}
}
public class MyThread extends Thread{
public MyThread(){}
public MyThread(String name){
super(name);
}
@Override
public void run() {
for(int i=0;i<200;i++)
{
System.out.println(getName()+" "+i);
}
}
}
public class MyThreadDemo {
public static void main(String[] args) {
//输出结果都是5,所以线程优先级默认是5
MyThread my1=new MyThread("线程1");
MyThread my2=new MyThread("线程2");
my1.setPriority(10);
System.out.println(my1.getPriority());
System.out.println(my2.getPriority());
my1.start();
my2.start();
}
}
5. 线程控制
方法名 | 说明 |
---|---|
static void sleep(long millis) | 使当前正在执行的线程停留(暂停执行)指定的毫秒数 |
void join() | 等待这个线程死亡,让调用它的线程先执行完毕 |
void setDaemon(boolean on) | 将此线程标记为守护线程,当运行的线程都是守护线程时,Java虚拟机将退出 |
public class MyThread extends Thread{
public MyThread(){}
public MyThread(String name){
super(name);
}
@Override
public void run() {
for(int i=0;i<200;i++)
{
System.out.println(getName()+" "+i);
try {
//sleep方法必须放到try...catch里
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public class MyThreadDemo {
public static void main(String[] args) {
MyThread my1=new MyThread("线程1");
MyThread my2=new MyThread("线程2");
my1.start();
my2.start();
}
}