`
oursleepless
  • 浏览: 9585 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java方法参数在多线程环境中的同步

阅读更多
JDK中java.util.Collections类提供了一些方便的操作集合的方法。例如:
public static void reverse(List<?> list)
public static void shuffle(List<?> list)
public static <T extends Comparable<? super T>> void sort(List<T> list)
等。
这些方法都是非线程安全的。在多线程环境下,假设一个线程正在对List进行排序,如果另一个线程同时从List中删除一个元素的话,很可能会导致异常发生。

如何修改上述的方法,使之线程安全呢?

在coding之前,我们必须了解有一下几个前提:

    1. 作为一个类库,我们不能预料其他开发人员如何使用该方法。即,如果其他开发人员在未加锁的环境中修改作为参数传递进来的List,即使我们简单地对该对象加锁, 也不能保护该对象。
    2. 如果对整个类或者实例加锁,成本太高,同时也无法解决问题1。


因此,例如要编写一个线程安全的排序方法,首先,要排序的列表必须是线程安全的,比如List就不适合作为参数(无法确保其是synchronized的),而必须替换为Vector。即方法需要修改为:
public <T> void sort(final Vector<T> list);

其次,要保证排序操作不能被其他线程打断,即排序操作需要加锁:
public <T> void sort(finalVector<T> list){
     synchronized (list) {
          //perform sorting on the list.  
     }
}


这两个条件缺一不可。测试代码如下 (TestSyncParam.java):
import java.util.Vector;
public class TestSyncParam {
     public void sort(Vector<Integer> list) {
          synchronized (list) {
          System.out.println("Start bubble sorting." + Thread.currentThread());
          for (int i = 0; i < list.size(); i++) {
               for (int j = list.size() - 1; j > i; j--) {
                    if (list.get(j) < list.get(j - 1)) {
                         int tmp = list.get(j - 1);
                         list.set(j - 1, list.get(j));
                         list.set(j, tmp);
                    }
                    try {
                         // slow down to give other threads a chance to touch 'list'
                         Thread.sleep(50);
                    } catch (InterruptedException e) {
                    }
               }
          }
          System.out.println("Bubble sorting done." + Thread.currentThread());
          }//end of sync
     }

     public static void main(String[] args) {
          int[] ii = new int[] { 12, 5, 18, 3, 50, 34, 4, 8, 11, 3, 25, 2 };
          final Vector<Integer> list = new Vector<Integer>();
          for (int i : ii)
               list.add(i);

          Runnable r1 = new Runnable() {
               public void run() {
                    try {
                         Thread.sleep(100);
                    } catch (InterruptedException e) {
                    }
                    System.out.println("Trying to remove first element. - " + Thread.currentThread());
                    Integer i = list.remove(0);
                    System.out.println("Removed '" + i + "', size: "+list.size()+" - " + Thread.currentThread());
               }
          };

          TestSyncParam tsp = new TestSyncParam();
          new Thread(r1).start();
          tsp.sort(list);
     }
}



执行结果如下:
Start bubble sorting.Thread[main,5,main]
Trying to remove first element. - Thread[Thread-1,5,main]
Bubble sorting done.Thread[main,5,main]
Removed '2', size: 11 - Thread[Thread-1,5,main]


总之,多线程环境下,我不建议将共享资源作为方法参数。如果必须,则该资源对象必须线程安全,方法的实现同时需要避免死锁。
分享到:
评论

相关推荐

    java多线程Demo

    3. 多线程同步与通信: 在多线程环境下,可能会出现数据竞争问题,为了解决这个问题,Java提供了多种同步机制,如synchronized关键字、wait/notify机制、Lock锁(ReentrantLock)等。synchronized用于控制对共享...

    java多线程设计模式_java_设计模式_多线程_多线程课题_

    Java多线程设计模式是Java开发中的核心概念,它涉及到如何高效、安全地在多个执行线程之间共享资源和协调任务。设计模式是解决特定问题的成熟方案,它们是编程经验的结晶,可以帮助开发者在面临多线程挑战时快速找到...

    Java多线程知识点总结

    Java多线程是Java编程语言中一个非常重要的概念,它允许开发者在一个程序中创建多个执行线程并行运行,以提高程序的执行效率和响应速度。在Java中,线程的生命周期包含五个基本状态,分别是新建状态(New)、就绪...

    java 多线程并发实例

    在Java编程中,多线程并发是提升程序执行效率、充分利用多核处理器资源的重要手段。本文将基于"java 多线程并发实例"这个主题,深入探讨Java中的多线程并发概念及其应用。 首先,我们要了解Java中的线程。线程是...

    java多线程查询数据库

    在Java编程中,多线程查询数据库是一种常见的优化策略,特别是在处理大数据量或者需要并行执行多个查询时。本文将详细探讨如何利用Java的多线程技术和线程池来实现并发查询数据库,以及相关的文件`BatchDataUtil....

    JAVA多线程编程技术PDF

    volatile确保变量在多线程环境中的可见性和有序性,避免缓存一致性问题。 此外,线程间通信也是多线程编程的重要方面。Java提供了wait(), notify()和notifyAll()方法,这些方法用于在线程间交换信息,但必须在同步...

    Java的多线程(java基础)

    Java的多线程是其编程语言中的一个重要特性,允许在单个程序中同时执行多个...在学习过程中,应重点掌握线程的创建、控制、同步和通信方法,以及如何处理线程安全问题,这样才能在实际项目中游刃有余地运用多线程技术。

    Java多线程编程实战指南-核心篇

    《Java多线程编程实战指南-核心篇》是一本深入探讨Java并发编程的书籍,旨在帮助读者掌握在Java环境中创建、管理和同步线程的核心技术。Java的多线程能力是其强大之处,使得开发者能够在同一时间执行多个任务,提高...

    java多线程详解(比较详细的阐述了多线程机制)

    在多线程环境中,异常处理也需特别注意,合理的try-catch-finally结构可以保证即使在多线程环境中也能正确处理异常。 总之,Java多线程是构建高性能并发应用的基础,理解并掌握线程的创建、同步、通信、协作模式...

    Java多线程示例之线程控制

    在Java编程中,多线程是一种常见的并发处理方式,它能充分利用CPU资源,提高程序的执行效率。本示例主要探讨了如何通过两种方法来控制Java中的线程数量,以达到优化性能和防止内存不足的目的。 首先,我们来看...

    Java多线程练习题

    在Java中,多线程的实现主要通过两种方式:继承Thread类和实现Runnable接口。理解并掌握多线程的使用对于任何Java开发者来说都至关重要。 一、线程的创建与启动 1. 继承Thread类:创建一个新的类,该类继承自Thread...

    Java多线程端口快速扫描

    - `CountDownLatch`:计数器,常用于多线程同步,例如,所有线程都完成任务后才能继续执行后续操作。 - `CyclicBarrier`:循环栅栏,允许一组线程等待其他线程到达某个点,然后一起继续执行。 4. **TCP连接与套接...

    java+多线程+同步详解源代码学习

    Java多线程与同步是Java编程中的核心概念,它们在构建高效、响应迅速的应用程序时起着至关重要的作用。在大型系统开发中,多线程技术使得程序能够同时执行多个任务,提高系统的并发性,而同步机制则确保了在多线程...

    java实现多线程文件传输

    在Java编程语言中,实现多线程文件传输是一种优化程序性能、提高系统资源利用率的有效方法。多线程允许我们同时处理多个任务,这对于大文件传输或需要并行处理的场景尤其有用。本篇文章将深入探讨如何使用Java实现多...

    C++JNI多线程回调java

    在多线程环境中,每个线程都有自己的执行上下文,这意味着当C++线程回调Java方法时,必须确保Java的同步机制正确地应用,以避免数据竞争和其他并发问题。Java中的`synchronized`关键字和`java.util.concurrent`包下...

    【JAVA多线程】多线程编程核心技术学习资料

    这份"Java多线程编程核心技术"的学习资料应该涵盖了以上所述的各个知识点,并可能深入讨论了如何在实际项目中有效地应用多线程,解决并发问题,优化性能。通过阅读这本书,开发者可以深入理解Java多线程编程的核心...

    现代多线程 JAVA和c++多线程实现 测试和调试

    在现代软件开发中,多线程技术已经成为必不可少的一部分,特别是在JAVA和C++这样的高级编程语言中。多线程允许程序同时执行多个任务,提高应用程序的响应性和效率。本资源主要探讨了如何在JAVA和C++中实现多线程,...

    Java多线程的总结

    Java多线程是Java编程中的一个核心概念,它在现代软件开发中扮演着至关重要的角色。多线程允许程序同时执行多个任务,提高了系统资源的利用率,提升了应用程序的响应速度和并发性能。对于大型分布式系统、Web应用...

    java+多线程+同步详解源码整理

    在多线程环境中,数据共享可能导致数据不一致,为了解决这个问题,Java提供了多种同步机制。包括: - **synchronized关键字**:用于方法或代码块,确保同一时间只有一个线程访问特定资源。 - **volatile关键字**...

    java多线程进阶

    这本书“java多线程进阶”显然旨在帮助读者深化这方面的理解,打通编程中的“任督二脉”,使开发者能够更加熟练地在并发环境中编写高效且稳定的代码。 1. **线程基础**:书中首先会介绍Java多线程的基础知识,包括...

Global site tag (gtag.js) - Google Analytics