说到线程,就要提到进程。说到进程,就得联想到程序。
程序是指令和数据的有序集合,程序本身是没有任何运行意义的,是一个静态的概念;而进程是程序一次执行的过程,是一个动态的概念,也是系统分配资源的单位,在一个进程中必然包含若干个线程,否则就没有任何意义。
线程:线程是一个应用程序在运行中的不同执行路径。
线程的作用
1.提高系统的CPU利用资源 2.提高应用程序的相应,增强用户的体验 3.改善程序结果
线程的状态
1. 创建状态
在程序中,使用构造方法创建了一个线程对象后,创建出的新的线程对象,就在创建状态,此时它已经有了相应的内存空间和其他资源。
2. 就绪状态
新建对象后,调用了start()方法,就可以启动线程。当线程启动时,就进入了就绪状态,此时的线程将进入线程列排队,等待CPU服务,已经具备了运行的条件。
3. 运行状态
当就绪状态被调用并获得处理器资源时,线程就进入了运行状态。此时会自动调用该线程的run()方法。run()方法定义了线程的操作和功能。
4. 阻塞状态
一个正在执行的线程在某些特殊的情况下,被人为的挂起或者需要消耗时间进行I/O等操作,线程都将进入阻塞状态。
5. 死亡状态
线程调用了stop()方法或run()方法执行结束后,将处于死亡状态。
线程的两种创建方式(一共有四种)
1. 继承Thread类
public class MyThread extends Thread{
@Override
public void run() {
System.out.println("运行了子线程:"+Thread.currentThread().getName());
}
}
在测试类中
//创建线程 MyThread myThread = new MyThread(); Thread thread = new Thread(myThread);
2. 实现Runnable接口
public class MyThread implements Runnable {
@Override
public void run() {
System.out.println("运行了子线程:" + Thread.currentThread().getName());
}
}
测试类中创建进程的方法同上。
获取当前线程
直接在主方法中调用 Thread 可以获取当前主线程。还可以调用Thread中的setName()方法修改线程的名字。
// 通过 Thread 获取当前 主线程
Thread thread = Thread.currentThread();
//获取名称
String threadName = thread.getName();
//修改线程名
thread.setName("MyThread");
当然,如果在子线程中调用Thread.currentThread() ,则获取到的就是子线程。
线程的强制执行
Thread类中的join()方法可以让指定的线程强制执行。例如要让 thread线程优于其他线程执行,就可以调用此方法。
这里的强制执行的意思是:例如说有三个线程 main , thread1 , thread2 ,想要让main执行完后再让其他线程运行。
例如下面的例子:
//主方法
public static void main(String[] args) throws InterruptedException {
MyThread myThread = new MyThread();
Thread thread = new Thread(myThread);
thread.start();
//thread.join;
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + i);
}
}
//MyThread类
public class MyThread implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + i);
}
}
}
不调用join()方法的运行:
调用join()方法的运行:
线程休眠和线程优先级
在Thread类中,sleep()|方法可以使进程休眠,但是仍在运行状态。相当于加长了线程的运行时间。
线程的优先级可以影响线程的执行顺序,但不是说决定了线程的运行顺序。同样是Thread类下,setPriority()方法可以修改线程的优先级,同时在Thread类中为我们提供了三个常量,用于修改线程的优先级。
Thread.MIN_PRIORITY 优先级最低(1) Thread.MAX_PRIORITY 优先级最高(10) Thread.NORM_PRIORITY 优先级中等(5)
获取和修改进程优先级的方法
//获取进程的优先级 getPriority() //修改线程的优先级 setPriority()
线程同步
同步,在Java中也就是说,要让多个线程共享同一个数据(对象),从而实现同步。
但是要实现同步的多线程序必须是通过实现Runnable接口构造的多线程。
我们可以通过两种方式来实现线程同步
1. 同步代码块
即将需要实现同步的代码块写在synchronized关键字括起来的代码块中。
synchronized (同步对象){ 需要同步的代码; }
2. 同步方法
即通过编写同步方法来实现同步,格式如下
synchronized 返回值 方法名 (参数 列表....){ 方法体; }