1. 前言
Java 多线程线程的线程不安全问题 – 创建多线程的两种方式
第一篇文章中,介绍了两种Java 实现多线程的方式(Thread and Runnable),此时是线程不安全的
本文介绍使用lock对其进行优化。
2. lock 解决线程不安全问题
2.1 lock 的使用方式:
1.实例化ReentrantLock
2.将同步代码放到try{}finnally{}
3.try 中调用lock.lock,使其变为单线程
4. finally{} 中放置解锁方法: lock.unlock
2.2 lock 解决 Thread 线程不安全问题
举例:
import java.util.concurrent.locks.ReentrantLock;
/**
* 使用 lock 解决 window1(继承实现多线程)的线程不安全问题
* @author JL
* @create 2022-04-24 17:13
*/
class window7 extends Thread {
// 1. 实例化ReentrantLock
ReentrantLock lock = new ReentrantLock();
private static int ticket = 100;
@Override
public void run() {
while (true) {
try{
// 2.在try中调用lock.lock
lock.lock();
if (ticket > 0) {
try { // 睡眠,让代码有更大机会异常
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);
ticket--;
} else {
break;
}
}finally {
lock.unlock();
}
}
}
}
public class window7Test {
public static void main(String[] args) {
// window1Test win = new window1Test();
window7 w1 = new window7();
window7 w2 = new window7();
window7 w3 = new window7();
w1.setName("窗口一");
w2.setName("窗口二");
w3.setName("窗口三");
w1.start();
w2.start();
w3.start();
}
}
2.3 lock 解决 Runnable 线程不安全问题
举例:
import java.util.concurrent.locks.ReentrantLock;
/**
* 使用 lock 解决 window2(使用runnable 实现多线程)的线程不安全问题
* @author JL
* @create 2022-04-25 10:13
*/
class window8 implements Runnable{
private int ticket = 100;
// 1. 实例化ReentrantLock,继承方式需加参数
ReentrantLock lock = new ReentrantLock(true);
@Override
public void run() {
while (true) {
try {
// 2.在try中调用lock.lock
lock.lock();
if (ticket > 0) {
try { // 睡眠,让代码有更大机会异常
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);
ticket--;
} else {
break;
}
} finally {
lock.unlock();
}
}
}
}
public class window8Test {
public static void main(String[] args) {
//window2Test window = new window2Test();
window8 win = new window8();
Thread t1 = new Thread(win);
Thread t2 = new Thread(win);
Thread t3 = new Thread(win);
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}
3. 总结
本文总结了通过 lock 解决 (Thread and Runnable )的线程不安全问题。并给出实例代码。