1.简介
线程是程序中的执行线程。Java虚拟机允许应用程序并发地运行多个执行线程。每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程。每个线程都可以或不可以标记为一个守护程序。当某个线程中运行的代码创建一个新Thread对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,新线程才是守护程序。当Java 虚拟机启动时,通常都会有单个非守护线程(它通常会调用某个指定类的main方法。Java 虚拟机会继续执行线程,直到下列任一情况出现时为止:
- 调用了Runtime类的exit方法,并且安全管理器允许退出操作发生。
- 非守护线程的所有线程都已停止运行,无论是通过从对run方法的调用中返回,还是通过抛出一个传播到run方法之外的异常。
2.Java实现线程2种方式
2.1 实现Runnable接口
public interface Runnable {
public abstract void run();
}
2.2 继承Thread类(其实也是实现Runnable接口的)
class Thread implements Runnable {
...
}
3.线程实现细节
3.1 线程优先级
public final static int MIN_PRIORITY = 1; // 最低优先级
public final static int NORM_PRIORITY = 5; // 默认优先级
public final static int MAX_PRIORITY = 10; // 最高优先级
3.2 线程状态,线程可以处于下列状态之一
- NEW 至今尚未启动的线程处于这种状态
- RUNNABLE 正在Java虚拟机中执行的线程处于这种状态
- BLOCKED 受阻塞并等待某个监视器锁的线程处于这种状态
- WAITING 无限期地等待另一个线程来执行某一特定操作的线程处于这种状态
- TIMED_WAITING 等待另一个线程来执行取决于指定等待时间的操作的线程处于这种状态
- TERMINATED 已退出的线程处于这种状态
3.3 线程状态转换
- NEW --> RUNNABLE
- RUNNABLE --> TERMINATED
- RUNNABLE --> BLOCKED
- BLOCKED --> RUNNABLE
- RUNNABLE --> WAITING
- WAITING --> RUNNABLE
- RUNNABLE --> TIMED_WAITING
- TIMED_WAITING --> RUNNABLE
3.4 可能常用API介绍
static int activeCount() 返回当前线程的线程组中活动线程的数目
static Thread currentThread() 返回对当前正在执行的线程对象的引用
ClassLoader getContextClassLoader() 返回该线程的上下文 ClassLoader
long getId() 返回该线程的标识符
String getName() 返回该线程的名称
int getPriority() 返回线程的优先级
Thread.State getState() 返回该线程的状态
ThreadGroup getThreadGroup() 返回该线程所属的线程组
static boolean holdsLock(Object obj) 当且仅当当前线程在指定的对象上保持监视器锁时,才返回 true
void interrupt() 中断线程
static boolean interrupted() 测试当前线程是否已经中断
boolean isAlive() 测试线程是否处于活动状态
boolean isDaemon() 测试该线程是否为守护线程
boolean isInterrupted() 测试线程是否已经中断
void join() 等待该线程终止
void join(long millis) 等待该线程终止的时间最长为 millis 毫秒
void join(long millis, int nanos) 等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒
void setDaemon(boolean on) 将该线程标记为守护线程或用户线程
void setName(String name) 改变线程名称,使之与参数 name 相同
void setPriority(int newPriority) 更改线程的优先级
static void sleep(long millis) 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响
static void sleep(long millis, int nanos) 在指定的毫秒数加指定的纳秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响
void start() 使该线程开始执行,Java虚拟机调用该线程的run方法
static void yield() 暂停当前正在执行的线程对象,并执行其他线程
void wait() 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待
void wait(long timeout) 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量前,导致当前线程等待
void wait(long timeout, int nanos) 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待
void notify() 唤醒在此对象监视器上等待的单个线程
void notifyAll() 唤醒在此对象监视器上等待的所有线程
4.线程状态转换Demo
public static void println(Object msg) { // 公用方法
System.out.println(msg);
}
4.1 NEW --> RUNNABLE
线程对象被new出来处于NEW状态,当调用start()后到线程结束前线程处于RUNNABLE状态
private volatile static boolean flag = true;
public static void main(String[] args) {
Thread thread = new Thread(()->{
while (flag) {
}
});
println(thread.getState());
thread.start();
println(thread.getState());
flag = false;
}
result:
NEW
RUNNABLE
4.2 RUNNABLE --> TERMINATED
处于RUNNABLE状态线程,当其执行完便处于TERMINATED状态
private volatile static boolean flag = true;
public static void main(String[] args) throws Exception {
Thread thread = new Thread(()->{
while (flag) {}
});
thread.start();
println(thread.getState());
flag = false;
Thread.sleep(1000);
println(thread.getState());
}
result:
RUNNABLE
TERMINATED
4.3 RUNNABLE --> BLOCKED (有点难控制 可能变成TIMED_WAITING)
处于RUNNABLE状态线程,当其因为synchronized等待或阻塞,此时线程状态为BLOCKED
private volatile static boolean flag = true;
public static synchronized void getRes() {
try {
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
Thread threadA = new Thread(()->{
while (flag);
getRes();
});
Thread threadB = new Thread(()->{
getRes();
});
threadA.start();
println(threadA.getState());
threadB.start();
Thread.sleep(1000);
flag = false;
Thread.sleep(1000);
println(threadA.getState());
}
result:
RUNNABLE
BLOCKED
4.4 BLOCKED --> RUNNABLE
线程BLOCKED后,当取得synchronized锁后,其状态又变成RUNNABLE
private volatile static boolean flag = true;
private volatile static boolean flagB = true;
public static synchronized void getRes() {
try {
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
Thread threadA = new Thread(()->{
while (flag);
getRes();
while (flagB);
});
Thread threadB = new Thread(()->{
getRes();
});
threadB.start();
threadA.start();
Thread.sleep(1000);
flag = false;
Thread.sleep(1000);
println(threadA.getState());
Thread.sleep(5000);
println(threadA.getState());
flagB = false;
}
result:
BLOCKED
RUNNABLE
4.5 RUNNABLE --> WAITING
线程处于RUNNABLE状态,当调用wait()/join()方法时,线程处于WAITING状态
private volatile static boolean flag = true;
private volatile static boolean flagB = true;
public static void main(String[] args) throws Exception {
Thread threadA = new Thread(()->{
while (flag);
});
Thread threadB = new Thread(()->{
while (flagB);
try {
threadA.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
threadA.start();
Thread.sleep(1000);
threadB.start();
println(threadB.getState());
flagB = false;
Thread.sleep(1000);
println(threadB.getState());
flag = false;
}
result:
RUNNABLE
WAITING
4.6 WAITING --> RUNNABLE
private volatile static boolean flag = true;
private volatile static boolean flagB = true;
private volatile static boolean flagC = true;
public static void main(String[] args) throws Exception {
Thread threadA = new Thread(()->{
while (flag);
});
Thread threadB = new Thread(()->{
while (flagB);
try {
threadA.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
while (flagC);
});
threadA.start();
Thread.sleep(1000);
threadB.start();
println(threadB.getState());
flagB = false;
Thread.sleep(1000);
println(threadB.getState());
flag = false;
Thread.sleep(1000);
println(threadB.getState());
flagC = false;
}
result:
RUNNABLE
WAITING
RUNNABLE
4.7 RUNNABLE --> TIMED_WAITING (TIMED_WAITING --> RUNNABLE)
private volatile static boolean flag = true;
private volatile static boolean flagB = true;
private volatile static boolean flagC = true;
public static void main(String[] args) throws Exception {
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
while (flag);
}
});
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
while (flagB);
try {
threadA.join(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
while (flagC);
}
});
threadA.start();
Thread.sleep(1000);
threadB.start();
println(threadB.getState());
flagB = false;
Thread.sleep(1000);
println(threadB.getState());
flag = false;
Thread.sleep(1000);
println(threadB.getState());
flagC = false;
}
result:
RUNNABLE
TIMED_WAITING
RUNNABLE
5.总结
感觉自己写这些状态转换很low,最近要先研究研究数据库,回头来搞高并发。
网友评论