浅谈Java线程状态与线程安全解析
线程状态
Java 中的线程一共有 6 个状态:
- New:新建状态,线程刚被创建后的状态。
- Runnable:就绪状态,表示线程已经创建好了,等 JVM 分配 CPU 时间片来运行。
- Blocked:阻塞状态,在以下情况下会进入阻塞状态:
- 线程调用 sleep() 方法,线程进入定时等待。
- 线程获取 synchronized 锁失败,线程进入阻塞状态。
- 线程等待某个条件,调用 wait() 方法,线程进入阻塞状态。
- Waiting:等待状态,在以下情况下会进入等待状态:
- 线程调用 Object.wait() 或 Thread.join() 方法时,线程进入等待状态。
- Timed_waiting:超时等待,在以下情况下会进入超时等待状态:
- 线程调用 Thread.sleep() 方法超时等待;
- 线程调用 Object.wait() 方法设置等待超时时间。
- Terminated:终止状态,表示线程已经执行完毕或者异常终止。
在多线程编程中,管理线程状态非常重要。控制线程状态需要使用 wait、notify、notifyAll 和 sleep 等方法,这些方法必须慎用。
线程安全
线程安全指的是多个线程同时访问同一份数据时,不会出现不可预期的结果或者数据混乱的现象。线程安全的解决方法主要有以下几种:
- synchronized 同步块:通过加锁和解锁来控制同时只能有一个线程访问共享数据。可以用在方法或代码块中。
public synchronized void method() {
// 线程同步代码块
}
synchronized(obj) {
// 线程同步代码块
}
- volatile 关键字:volatile 修饰的变量每次被访问时,都会从内存中重新读取最新的值。
public class VolatileDemo {
private volatile boolean flag = false;
public void setFlag(boolean flag) {
this.flag = flag;
}
public void printFlag() {
while (!flag) {
System.out.println("flag = " + flag);
}
}
public static void main(String[] args) {
VolatileDemo vd = new VolatileDemo();
new Thread(() -> {
vd.setFlag(true);
System.out.println(Thread.currentThread().getName() + " flag:" + vd.flag);
}, "A").start();
new Thread(() -> {
vd.printFlag();
System.out.println(Thread.currentThread().getName() + " flag:" + vd.flag);
}, "B").start();
}
}
- ReentrantLock:ReentrantLock 是一个可重入的互斥锁,可以代替 synchronized 给共享数据加锁。
public class ReentrantLockDemo {
private int num = 0;
private Lock lock = new ReentrantLock();
public void increaseNum() {
lock.lock();
try {
num++;
System.out.println(Thread.currentThread().getName() + " num: " + num);
} finally {
lock.unlock();
}
}
public void decreaseNum() {
lock.lock();
try {
num--;
System.out.println(Thread.currentThread().getName() + " num: " + num);
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
ReentrantLockDemo obj = new ReentrantLockDemo();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
obj.increaseNum();
}
}, "A").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
obj.decreaseNum();
}
}, "B").start();
}
}
通过上述例子可以了解到线程状态和线程安全的相关知识,实际开发中,为了保证线程安全和线程状态,我们需要注意以下一些事项:
- 对共享数据进行同步控制。
- 尽量使用不可变对象,减少共享数据。
- 使用线程安全的类,例如 Vector、Collections.synchronizedXXX 等。
希望这篇文章对大家理解 Java 线程状态和线程安全有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:浅谈java线程状态与线程安全解析 - Python技术站