线程的状态

在import java.lang.Thread.State枚举类里列出了6种线程状态

状态 意义
NEW A thread that has not yet started is in this state.(创建后未调用start方法)
RUNNABLE A thread in the runnable is executing in the Java virtual machine but it may waiting for other resources from the operating system such as processor.(可执行状态,可能在执行,也可能在等待其他os资源)
BLOCKED A thread that is blocked(阻塞) waiting for a monitor lock(监视器锁) to enter注① a synchronized block/method or reenter a synchronized block/method after calling{@link Object#wait() Object.wait}.
WAITING A thread that is waiting indefinitely for another thread to perform a particular action is in this state.(调用Object.wait())、Thread.join()、LockSupport.park()线程就会进入等待状态。注②)
TIMED_WAITING A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.(调用Thread.sleep()、Thread.join()、Object.wait())、LockSupport.parkNanos()、LockSupport.parkUntil()方法就会进入TIMED_WATTING。)
TERMINATED A thread that has exited is in this state.
  • ①:java使用监视器同步模型实现的synchronized锁,synchronized的获取锁和释放锁字节码表示为monitorenter和monitorexit,因此这里的enter指的就是等待monitorenter。
  • ②:例如:调用Object.wait()方法进入WATTING的线程在等待另一个线程在这个对象调用Object.notify()或者Object.notifyAll()。调用Thread.join()的线程在等待指定线程终止。

1. Java中的线程

java.lang.Thread
java中的线程是抢占调度模式,Java虚拟机允许并发执行多个线程,每个线程都有一个优先级,高优先级执行优于低优先级。每个线程都可以或不可以标记为一个守护程序。当某个线程中运行的代码创建一个新 Thread 对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,新线程才是守护程序。

当 Java 虚拟机启动时,通常都会有单个非守护线程(它通常会调用某个指定类的 main 方法)。Java 虚拟机会继续执行线程,直到下列任一情况出现时为止:

  • 调用了 Runtime 类的 exit 方法,并且安全管理器允许退出操作发生。
  • 非守护线程的所有线程都已停止运行,无论是通过从对 run 方法的调用中返回,还是通过抛出一个传播到 run 方法之外的异常。

每个线程都有一个标识名,多个线程可以同名。如果线程创建时没有指定标识名,就会为其生成一个新名称。

创建线程

方法1 继承Thread类,重写run()方法

1
2
3
4
5
6
7
8
9
10
11
12
class PrimeThread extends Thread {

public static void main(){
PrimeThread p = new PrimeThread(143);
p.start();

}
@Override
public void run() {
....
}
}

方法二 实现Runnable接口,创建Thread类的时候把实现的接口作为参数传递

1
2
3
4
5
6
7
8
9
10
11
class PrimeRun implements Runnable {
public static void main(){
PrimeThread p = new PrimeThread(143);
new Thread(p).start();

}
@Override
public void run() {
....
}
}

方法三 匿名内部类 创建线程

runable同

1
2
3
4
5
6
new Thread(){
@Override
public void run(){
....
}
}

正在运行的线程

static Thread currentThread() :返回对当前正在执行的线程对象的引用。

1
Thread.currentThread().getName()

设置线程名称

1
2
Thread.setName();
Thread.getName();

线程睡眠

static void sleep(long millis): 线程休眠。

线程同步(锁)

synchronized同步代码块

1
2
3
4
执行时获得锁  执行完毕释放锁
sychronized(提供锁的对象,比如this){
临界代码
}

synchronized同步方法

1
2
3
权限修饰 synchronized 返回值 方法名(...){
临界代码
}

synchronized同步类

权限修饰 synchronized class 。。。

synchronized静态代码块

1
2
3
4
5
权限修饰 返回值 方法名(...){
sychronized(RunnableImpl.class){
临界代码
}
}

ReentrantLock锁

用java.util.concurrent.locks包下ReentrantLock类,它实现了Lock接口

  • void lock()获取锁
  • void unlock()释放锁
  • lockInterruptibly()获得锁,但优先响应中断
  • tryLock()尝试获得锁,成功返回true,失败返回false
  • tryLock(long time, TimeUnit unit)在给定时间尝试获得锁

好处:无论程序是否有异常都能释放锁

1
2
3
4
Lock lock = new ReentrantLock();
lock.lock();
...
lock.unlock();

什么是intrinsic lock(内在锁)和monitor lock(监视器锁)

在JVM中,每个对象和类在逻辑上都是和一个监视器相关联的,为了实现监视器的排他性监视能力,JVM为每一个对象和类都关联一个锁,锁住了一个对象,就是获得对象相关联的监视器。

扩展

JUC(Lock)和Monitor Object(Synchronized)机制区别

Java中锁和监视器有何区别?有何代码可以举例?