背景知识
涉及多线程编程时都会考虑线程安全的问题,那什么是非线程安全呢?
非线程安全:多个线程对同一个对象的同一个全局变量进行操作时会出现值被更改、值不同步的情况,进而影响程序的执行流程
*该书作者在解释非线程安全时提到的是实例变量,而我在本文中使用的是全局变量,若我理解错了希望各位能够指出!
基础知识
实现方式
在java.lang
包下提供了两种实现多线程的方式
继承
java.lang.Thread
类并重写run()
然后调用start()
启动线程实现
java.lang.Runnable
接口并重写run()
然后借助java.lang.Thread
类调用start()
启动线程
图1
从图1中我们可以看出java.lang.Thread
是实现类java.lang.Runnable
接口的,由上述两种方式实现的多线程在效果上无区别,但由于java
仅支持单继承一般建议使用实现java.lang.Runnable
接口的方式实现多线程
停止线程
stop()
已经被废弃了
@Deprecated
public final void stop()
@Deprecated
public final synchronized void stop(Throwable obj)
interrupt()
并不会真的中断一个线程,而是改变中断标记
使用interrupted()
或isInterruped()
配合return
、抛出异常来停止线程
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
public boolean isInterrupted() {
return isInterrupted(false);
}
private native boolean isInterrupted(boolean ClearInterrupted);
分析代码可知interrupted()
针对的是当前线程即执行该代码的线程,而isInterrupted()
针对的是该方法所属的线程
暂停线程
suspend()
、resume()
用于暂停线程和恢复线程,目前已被弃用
线程优先级
- 优先级较高的线程得到的CPU资源较多,换句话说就是CPU优先执行优先级较高的线程对象中的任务
- 优先级具有继承性,即当前正在执行的线程会继承调用线程的优先级
- 高优先级的线程总是大部分先执行完,但不代表高优先级的线程全部先执行完
在Thread类中定义类三个关于优先级级别的常量:
/**
* The minimum priority that a thread can have.
*/
public final static int MIN_PRIORITY = 1;
/**
* The default priority that is assigned to a thread.
*/
public final static int NORM_PRIORITY = 5;
/**
* The maximum priority that a thread can have.
*/
public final static int MAX_PRIORITY = 10;
设置线程的优先级可以使用如下方法进行设置
public final void setPriority(int newPriority)
常用方法:
currentThread()
获得当前调用线程的信息
isAlive()
检测线程是否属于活动状态
活动状态就是线程已经启动且尚未终止,线程处于正在运行或准备开始运行的状态,就认为线程是“存活“
sleep(long millis)
在指定的毫秒内让当前线程暂停执行(休眠)
getId()
获取线程的唯一标识
yield()
放弃当前的CPU资源,让给其它的任务去占用,何时放弃何时收回,时间不可控
为了避免出现多线程安全问题,java中提供了synchronized
关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码