本文共 2382 字,大约阅读时间需要 7 分钟。
在 JVM 中,如果有多个线程同时操作同一资源,可能会导致线程不安全。以下是一个例子:
在 railwayReservationTest 类中,ticketNums 是一个共享资源。多个线程同时对 ticketNums 进行操作,会出现线程不安全的情况。例如,可能会出现逻辑错误,如同一张票被多次购买。
package com.annan.demo01;public class TestThread4 implements Runnable { private int ticketNums = 10; public void run() { while (true) { if (ticketNums <= 0) { break; } try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println Thread.currentThread().getName() + "--->买到了第" + ticketNums-- +"张票"); } } public static void main(String[] args) { TestThread4 testThread4 = new TestThread4(); new Thread(testThread4, "吉良吉影").start(); new Thread(testThread4, "黄牛党").start(); new Thread(testThread4, "神父").start(); }}
###龟兔赛跑优化方案
在多线程环境下,给程序增加游戏性可以更直观地展示多线程问题的影响。以下是一个优化后的例子:
再来看 raceTest 类的优化方案:
package com.annan.demo01;public class Race implements Runnable { private static String winner; public void run() { for (int i = 0; i <= 100; i++) { if (Thread.currentThread().getName() == "兔子" && i == 50) { try { Thread.sleep(1); } catch (InterruptedException e) { throw e; } } boolean flag = isGameOver(i); if (flag) { break; } System.out.println(Thread.currentThread().getName() + "--->跑了" + i + "步"); } } public static boolean isGameOver(int steps) { if (winner != null) { return true; } if (steps >= 100) { winner = Thread.currentThread().getName(); System.out.println("获胜者是" + winner); return true; } return false; } public static void main(String[] args) { Race race = new Race(); new Thread(race, "兔子").start(); new Thread(race, "乌龟").start(); }}
###优化后的分析
我们在优化过程中做了以下改进:
isGameOver
,更符合Java命名规范。###总结
-.raceExample 线程不安全的本质原因在于共享资源没有得当的保护,这种现象在生产环境中可能导致严重的后果。
建议可以参考 Object
类的 synchronized
关键字或 Lock
类实现线程安全问题。
转载地址:http://dlblz.baihongyu.com/