JAVA基础—14.多线程

爱转圈笔记

勤思、体悟、总结、分享

多线程

Process & Thread

什么是进程(Process)

在操作系统中,每个运行中的程序就是一个进程。


什么是线程(Thread)

在一个运行的程序中,内部可能包含多个顺序执行的指令流,每个指令流就是一个线程,线程是进程的执行单元,每个线程是相互独立的。


并发性和并行性

  • 并发性:在同一时刻只能有一条指令执行,但多个进程指令被快速轮换执行,在宏观上使多个进程有同时执行的效果。
  • 并行性:在同一时刻,有多条指令在多个处理器上同时执行。

多线程的优势

  • 进程之间不能共享内存,线程之间共享内存非常容易。
  • 系统创建进程时需要重新分配系统资源,穿件线程则代价小得多,所以使用多线程来实现多任务并发比多进程的效率要高。
  • JAVA内置了多线程功能支持,简化了多线程编程。

线程的创建

  1. 继承Thread类并重写run()方法
public class FirstThread extends Thread {
	//通过继承Thread类创建线程
	@Override
	public void run() {
		//此处为线程执行内容
	}	
}
  1. 实现Runnable接口并实现run()方法
public class SecondThread implements Runnable {
	//通过实现Runnable接口创建线程
	@Override
	public void run() {
		//此处为线程执行内容
	}
}

推荐使用实现接口的形式创建线程,因为使用接口,该线程还可以继承其他父类。


线程的启动

  • 通过start()方法启动线程,而不是run()方法。
  • 只能对处于新建状态的线程使用start()方法。
public class LearnThread {
	public static void main(String[] args) {
		//启动继承Thread类的线程
		new FirstThread().start();
		//启动实现Runable接口的线程
		new Thread(new SecondThread()).start();
	}
}

线程的生命周期

  1. 新建状态(New):

    • 用new操作符创建一个线程时,线程还没有开始运行,此时线程处于新建状态。
    • 线程处于新建状态时,程序还没有开始运行线程中的指令。
  2. 就绪状态(Runnable)

    • 一个新创建的线程并不自动开始运行,要执行线程,必须调用线程的start()方法。
    • 当线程对象调用start()方法即启动了线程,start()方法创建线程运行的系统资源,并调度线程运行run()方法。
    • 当start()方法返回后,线程就处于就绪状态。
    • 处于就绪状态的线程并不一定立即运行run()方法,线程还必须同其他线程竞争CPU时间,只有获得CPU时间才可以运行线程,因此此时可能有多个线程处于就绪状态。
    • 对多个处于就绪状态的线程是由Java运行时系统的线程调度程序(thread scheduler)来调度的。
  3. 运行状态(Running)

    • 当线程获得CPU时间后,它才进入运行状态,真正开始执行run()方法。
  4. 阻塞状态(Blocked)

    • 所谓阻塞状态是正在运行的线程没有运行结束,暂时让出CPU,这时其他处于就绪状态的线程就可以获得CPU时间,进入运行状态。
    • 产生阻塞状态的原因
      • 线程通过调用sleep方法进入睡眠状态;
      • 线程调用一个在I/O上被阻塞的操作,即该操作在输入输出操作完成之前不会返回到它的调用者;
      • 线程试图得到一个锁,而该锁正被其他线程持有;
      • 线程在等待某个触发条件;
  5. 死亡状态(Dead)

    • 有两个原因会导致线程死亡:
      • run方法正常退出而自然死亡,
      • 一个未捕获的异常终止了run方法而使线程死亡。

线程的常用方法

  • join():让一个线程等待另一个线程完成,当前线程会等待调用join方法的线程执行完再执行。例如,a线程中调用了b.join(),那a线程会等待b执行完再执行。
  • sleep(long millis):使当前线程暂停millis毫秒并进入阻塞状态,期间线程不会执行。
  • yield():使当前线程暂停,但不会阻塞线程,调度器很可能在其暂停后又将其调度出来执行,所以在宏观层面来看,yield()方法无用的效果。
  • setPriority(int newPriority):设置线程优先级,范围是1~10。
  • getPriority():返回线程优先级。

线程同步

在多线程并发编程时,很有可能出现线程安全问题(多个线程同时访问和操作同一数据、死锁等)。

  • 线程安全问题的常用解决办法(不详细介绍,自行查阅)。
    • 同步代码块
    • 同步方法
    • 同步锁(Lock)

猜你喜欢

转载自blog.csdn.net/wyd288/article/details/86676151