欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java多线程编程核心技术】-- 第一章:java多线程技能

程序员文章站 2022-05-06 08:01:31
...

第一章总结

本章主要介绍了Thread类API的基本功能,使用这些API的的过程当中会出现一些意想不到的情况,学习和掌握一些常用情况,就掌握了多线程开发的命脉与习性,是学习多线程更深层知识的基础。

第一章知识点

基本概念

进程:是操作系统结构的基础,是一次程序的执行,是一个程序及其数据在处理机上的顺序执行时所发生的活动,也是系统进行资源分配和调度的一个独立单位。
线程:线程可以理解为在进程中独立运行的子任务。比如QQ.exe运行时会有很多子任务在同时运行,如视频线程、下载文件线程等,多线程的优点就是可以最大限度的利用CPU的空闲时间来处理其它任务,CPU在不同的任务之间的切换速度非常快,所以给使用者的感受就是这些任务似乎是在同时运行的。

如何使用多线程

  • 继承Thread类
    由于java单继承的局限性,所以通常用实现Runnable接口的方使用多线程
  • 实现Runnable接口
    实现Runnable接口,将Runnable对象传入Thread对象中调用start()方法启动线程

currentThread()方法

currentThread()方法返回代码段正在被哪个线程调用

public class MyThread extends Thread {
	public MyThread(){
		system.out.println(Thread.currentThread().getName()); //结果为main
	}
	public void run(){
		system.out.println(Thread.currentThread().getName()); //结果为Thread-0
	}
}

public static void main(String args[]){
	system.out.println(Thread.currentThread().getName());//结果为main
	MyThread myThread = new MyThread();
	myThread.start();
}

isAlive()方法

方法返回true或者false,判断当前的线程是否处于活动状态,活动状态就是指线程已经启动并且尚未终止。线程处于正在运行或准备开始运行的状态,就认为线程是“存活”的。在启动线程之前都是false。

sleep()方法

Thread类中的静态方法sleep(),当一个执行中的线程调用了Thread的sleep()方法后(哪个线程调用了Thread.sleep()方法哪个线程就处于睡眠状态),调用线程会暂时让出时间的执行权,这期间不参与cpu的调度,但是该线程持有的锁是不让出的。时间到了会正常返回,线程处于就绪状态,然后等待cpu的调度,获取到cpu资源后又会处于运行状态。

getId()方法

Thread类中的静态方法,该方法的作用是取得线程的唯一标识。

Thread.currentThread().getId();  //在main方法中执行时返回1

停止线程

停止线程意味着在线程执行完任务之前停掉当前正在执行的操作,一定需要做好防范措施。Thread.stop()方法是不安全的方法,而且已经被弃用了;现在使用的方法多是使用Thread.interrupt()方法,这个方法不会马上终止一个正在执行的线程,还需要加入一个判断才能完成线程的停止。
java中主要有三种方式停止线程

  • 使用退出标识,使线程正常退出
  • 使用stop、suspend、resume方法都是过期作废的方法,使用它们可能会造成预想不到的结果
  • 使用interrupt方法中断线程

interrupted()和isInterrupted()方法区别

interrupted():,Thread类的静态方法,测试当前线程是否已经中断,当前线程是指运行this.interrupted()方法的线程,同时该方法也有状态清除的功能

例子一:验证测试的是当前线程

public static void main(){
	MyThread myThread = new MyThread();
	thread.start();
	Thread.sleep(1000);
	system.out.println(myThread.interrupted());//结果为false
	system.out.println(myThread.interrupted());//结果为false
	//说明了interrupted()方法是测试当前线程是否已经中断,当前线程是main线程,main线程从未中断过
	//该方法也具有清除线程中断状态的功能,所以连续两次调用都会返回false

}

例子二:验证具有状态清除功能

public static void main(){
	Thread.currentThread().interrupt();
	system.out.println(Thread.interrupted());//结果为true
	system.out.println(Thread.interrupted());//结果为false
	//该方法也具有清除线程中断状态的功能,第一次调用会清除线程的中断状态
	//所以第二次调用的时候会返回false
}

isInterrupted():不是Thread类的静态方法,测试线程Thread对象是否已经中断,不会将中断状态清除为false。

例子:

public static void main(){
	MyThread myThread = new MyThread();
	thread.start();
	Thread.sleep(1000);
	system.out.println(myThread.isInterrupted());//结果为true
	system.out.println(myThread.isInterrupted());//结果为true
	//说明了isInterrupted()方法是测试线程Thread对象是否已经中断,当前线程是main线程,main线程从未中断过
}

线程在沉睡中停止将会抛出异常
例子:

public class MyThread extends Thread {
	public void run(){
		try {
			Thread.sleeep(200000);
		}catch(InterruptedException e){
			system.out.println("在沉睡中停止了," + this.isInterrupted());  
			//结果将打印出来,sleep状态下停止停止某个线程,也会清除线程中断状态,打印出false
			e.printStackTrace();
		}
		
	}
}

public static void main(String args[]){
	MyThread myThread = new MyThread();
	myThread.start();
	Thread.sleep(200);  //main线程睡眠,容易使MyThread线程获取CPU执行
	thread.interrupt();
}

暂停线程

暂停线程意味着此线程还可以恢复运行,在java多线程中,可以使用suspend()方法暂停线程,使用resume()方法恢复线程的执行。
suspend()方法是过期作废的方法,现在也不会使用此方法了。

yield()方法

yield()方法的作用是放弃当前的CPU资源,将它交给其他的任务去占用CPU的执行时间,调用该方法之后线程又会处于就绪状态,参与到争夺CPU的竞争当中。

线程的优先级

线程可以划分为优先级,优先级较高的线程得到CPU的资源较多,设置线程优先级有助于帮“线程规划器”确定下一次选择哪一个线程优先执行打,但是这也不是绝对的,实际的还是要看CPU的执行情况。设置优先级使用setPriority()方法,该方法源码如下:
java多线程编程核心技术】-- 第一章:java多线程技能
线程的优先等级分为1–10这10个等级,JDK常使用如下三个常量来预置定义优先级的值,代码如下
java多线程编程核心技术】-- 第一章:java多线程技能
线程优先级还具有继承特性
比如A线程启动B线程,则B线程的优先级和A线程是一样的。

守护线程

在java线程中有两种线程,一种是用户线程,一种是守护线程。
守护线程是一种特殊的线程,当进程中不存在非守护线程时,则守护线程自动销毁。典型的守护线程就是垃圾回收线程,通过调用thread.setDaemon(true) 把thread设置成后台线程。