Java多线程实践:同步代码块案例对比

原创 ╰半夏微凉° 2024-10-10 07:00 136阅读 0赞

在Java多线程编程中,同步代码块是一种常用的互斥机制。这里我们将通过一个案例对比来阐述这一点。

案例一:无同步的线程操作

  1. class Counter {
  2. private int count = 0;
  3. public synchronized void increment() {
  4. count++;
  5. }
  6. public synchronized int getCount() {
  7. return count;
  8. }
  9. }
  10. // 多个线程同时访问Counter实例
  11. Thread t1 = new Thread(() -> {
  12. Counter counter = new Counter();
  13. for (int i = 0; i < 5; i++) {
  14. counter.increment(); // 直接操作,无同步保护
  15. }
  16. }));
  17. Thread t2 = new Thread(() -> {
  18. Counter counter = new Counter();
  19. for (int i = 0; i < 5; i++) {
  20. counter.getCount(); // 不直接修改值,但读取时未同步保护
  21. }
  22. });
  23. t1.start();
  24. t2.start();

在这个案例中,线程t1t2同时访问同一个Counter实例。由于没有同步代码块进行保护,结果是不可预知的。

案例二:使用synchronized关键字的同步代码块

  1. class Counter {
  2. private int count = 0;
  3. public synchronized void increment() {
  4. count++;
  5. notifyAll(); // 发送通知,等待线程重新进入方法
  6. }
  7. public synchronized int getCount() {
  8. while (count == 0) { // 确保计数器值不为0
  9. try {
  10. wait();
  11. } catch (InterruptedException e) {
  12. e.printStackTrace();
  13. }
  14. }
  15. return count;
  16. }
  17. }
  18. // 多个线程同时访问Counter实例
  19. Thread t1 = new Thread(() -> {
  20. Counter counter = new Counter();
  21. for (int i = 0; i < 5; i++) {
  22. counter.increment(); // 同步代码块保护,确保结果正确
  23. }
  24. });
  25. Thread t2 = new Thread(() -> {
  26. Counter counter = new Counter();
  27. for (int i = 0; i < 5; i++) {
  28. counter.getCount(); // 同样,同步代码块确保读取的值是正确的
  29. }
  30. });
  31. t1.start();
  32. t2.start();

在案例二中,我们为increment()getCount()方法添加了synchronized关键字,这使得它们在同一时间只能被一个线程访问。

这样做的结果就是无论多个线程同时对同一个实例进行操作,都能够保证数据的完整性和一致性。

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

发表评论

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

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

相关阅读