新手常犯:Java多线程并发编程错误实例

原创 青旅半醒 2024-12-04 05:09 74阅读 0赞

在Java多线程并发编程中,新手可能会遇到各种错误。以下是一些常见的错误实例:

  1. 未初始化的静态变量

    1. // 错误:静态变量未初始化
    2. static int sharedVariable = 0;
    3. // 正确:使用ThreadLocal存储局部变量
    4. ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
  2. 死锁

    1. // 错误:线程1等待线程2释放资源
    2. class LockResource {
    3. private Object lock;
    4. public LockResource() {
    5. this.lock = new Object();
    6. }
    7. public synchronized void acquireLock() throws InterruptedException {
    8. while (lock != null) {
    9. wait(lock);
    10. }
    11. lock = new Object();
    12. }
    13. public synchronized void releaseLock() {
    14. if (lock != null) {
    15. lock = null;
    16. notifyAll();
    17. }
    18. }
    19. }
    20. class WorkerThread extends Thread {
    21. private LockResource resource;
    22. public WorkerThread(LockResource resource) {
    23. this.resource = resource;
    24. start();
    25. }
    26. @Override
    27. public void run() {
    28. try {
    29. resource.acquireLock(); // 正确:先获取锁,再执行任务
    30. // 任务示例
    31. Thread.sleep(2000); // 模拟耗时操作
    32. resource.releaseLock(); // 正确:释放锁后通知其他线程
    33. } catch (InterruptedException e) {
    34. e.printStackTrace();
    35. }
    36. }
    37. }
    38. class Main {
    39. public static void main(String[] args) {
    40. LockResource resource = new LockResource();
    41. WorkerThread worker1 = new WorkerThread(resource);
    42. WorkerThread worker2 = new WorkerThread(resource);
    43. worker1.start(); // 启动线程
    44. worker2.start(); // 同理
    45. try {
    46. worker1.join(); // 等待worker1完成任务
    47. worker2.join(); // 同理,等待worker2完成任务
    48. } catch (InterruptedException e) {
    49. e.printStackTrace();
    50. }
    51. }
    52. }
  3. 共享数据未同步

    1. class Counter {
    2. private int count;
    3. public Counter() {
    4. this.count = 0;
    5. }
    6. // 错误:返回值为引用,但没有同步更新count
    7. public synchronized int incrementCounter() {
    8. return ++count; // 错误:直接操作count,未同步
    9. }
    10. public synchronized int decrementCounter() {
    11. return --count; // 同理
    12. }
    13. public synchronized int getCount() {
    14. return count;
    15. }
    16. }
    17. class WorkerThread extends Thread {
    18. private Counter counter;
    19. public WorkerThread(Counter counter) {
    20. this.counter = counter;
    21. start();
    22. }
    23. @Override
    24. public void run() {
    25. for (int i = 0; i < 1000; i++) {
    26. // 在这里操作counter,模拟耗时操作
    27. counter.incrementCounter(); // 错误:未同步更新count
    28. // 模拟耗时操作
    29. try {
    30. Thread.sleep(100);
    31. } catch (InterruptedException e) {
    32. e.printStackTrace();
    33. }
    34. }
    35. // 正确示例:使用CountDownLatch同步更新counter
    36. counter.countDown(); // 系统会等待countdown信号到达,然后更新count为0
    37. System.out.println("WorkerThread done." + counter.getCount()); // 输出: WorkerThread done. 0
    38. }
    39. }
    40. class Main {
    41. public static void main(String[] args) {
    42. Counter counter = new Counter();
    43. WorkerThread worker1 = new WorkerThread(counter);
    44. WorkerThread worker2 = new WorkerThread(counter);
    45. worker1.start(); // 启动线程
    46. worker2.start(); // 同理
    47. try {
    48. worker1.join(); // 等待worker1完成任务
    49. worker2.join(); // 同理,等待worker2完成任务
    50. // 正确示例:检查counter的值,确保更新同步
    51. if (counter.getCount() != 0) {
    52. System.out.println("Counter value not updated correctly. Counter count: " + counter.getCount());
    53. throw new RuntimeException("Counter synchronization error.");
    54. }
    55. } catch (InterruptedException e) {
    56. e.printStackTrace();
    57. }
    58. System.out.println("Main done.");
    59. }
    60. }

请根据你的实际需求,修改上述代码以避免错误。

文章版权声明:注明蒲公英云原创文章,转载或复制请以超链接形式并注明出处。

发表评论

表情:
评论列表 (有 0 条评论,74人围观)

还没有评论,来说两句吧...

相关阅读