如何使此函数线程安全?

时间:2018-10-25 02:34:30

标签: java

shuffle

我是否必须使用synced关键字使其线程安全。如果方法已同步,我是否必须使用Vector和Hashtable。

或者,如果我使用Vector和Hashtable,将n=10 x=df[df['col3'] == 'group2'].index.values numpy.random.shuffle(x) df.loc[x[:n],'tochange']='something' 变量移至<div *ngFor="let key of objectKeys(todo)"> <ion-item *ngIf="getObjectDataType(key) == 'String' && key != 'Description'"> <ion-label floating>{{key}}</ion-label> <ion-input type="text" [(ngModel)]="this['todo.' + key]" [ngModelOptions]="{ standalone : true }"></ion-input> </ion-item> <ion-item *ngIf="getObjectDataType(key) == 'String' && key == 'Description'"> <ion-label floating>{{key}}</ion-label> <ion-textarea [(ngModel)]="this['todo.' + key]" [ngModelOptions]="{ standalone : true }"></ion-textarea> </ion-item> <ion-item *ngIf="getObjectDataType(key) == 'Date' && key != 'Description'" style="margin-top: 15px;"> <ion-label>{{key}}</ion-label> <ion-datetime displayFormat="MM/DD/YYYY hh:mm A" [min]="yesterDayStr" [(ngModel)]="this['todo.' + key]" [ngModelOptions]="{ standalone : true }"></ion-datetime> </ion-item> </div> 并将其传递给public class Sol { static Map<Integer, List<String>> emap; static List<Integer> sortSalaries(List<List<String>> workers) { List<Integer> res = new ArrayList<Integer>(); emap = new HashMap<>(); for (List<String> e: workers) emap.put(Integer.parseInt(e.get(0)), e); for(List<String> worker: workers ) { //accessing workers ..... } Collections.sort(res); return res; } public static int dfs(int eid) { List<String> employee = emap.get(eid); int salary=0; String ans = employee.get(3); for (int i=0;i<ans.length();i=i+2) { // accesing emap ...... } return salary; } } 怎么办。 如果我在这种情况下不使用同步关键字,就可以了。

2 个答案:

答案 0 :(得分:1)

  1. 从外部访问保护emap
  2. 初始化emap以排除NPE

示例:

public final class Sol {

    private static final Map<Integer, List<String>> emap = new HashMap<>();

    static List<Integer> sortSalaries(List<List<String>> workers) {
        synchronized (Foo.class) {
            for (List<String> e : workers)
                emap.put(Integer.parseInt(e.get(0)), e);
        }

        // do smth, not access emap
    }

    public static synchronized int dfs(int eid) {
        // do smth with accessing emap
    }
}

sortSalaries中,可以用synchoronized最小化for loop块。在dfs中,您可以在方法的不同位置访问emap,因此必须同步化enire方法。

在这里使用ConcurrentHashMapVector都无济于事,因为将get/set元素添加到集合中,可以对其进行更改,这对于dfs方法而言不可行:调用时emap会发麻。

答案 1 :(得分:1)

我在评论中问您一个问题-您了解为什么这些方法从多个线程中调用时不是线程安全的吗?,您为我指出了一个链接,但未指明您是否真正理解它是否,为什么您认为您的课程不是线程安全的,所以我提供了一些背景知识,而不是直接回答问题。

简短讨论

当您开始在运行程序/调用线程之间共享数据时,任何类或其方法可能都不是线程安全的。默认情况下,您的类是线程-如果线程之间没有共享数据,则是安全的,因此最简单的使您的类成为线程的方法-安全是停止在线程之间共享数据,在您的情况下,将删除-emap(因为它是一个类状态并且在方法中使用)和List<List<String>> workers(这是不确定的,因为它从调用方传递的引用和不同的方法调用将在同一个实例上运行或可能将不同的实例传递给此方法),并用方法局部变量替换它们。

方法局部变量是线程安全的-默认情况下是安全的,因为将为每个调用创建和销毁新实例。

如果您不能执行此操作或不可行,请按照oleg.cherednik的回答在块级别或方法级别同步变量-emap。请记住,有多种方法可以最简单地在Java中使用synchronized关键字进行同步。

现在为方法参数-List<List<String>> workersint eid,不需要为eid进行同步,因为您只是在读取它而不更新,并且它也不通过引用而是通过值传递由于类型是原始的。

如果要将同一列表实例从不同的线程传递给此方法的调用,则需要同步访问List<List<String>> workers。请参考Gray's Answer - Here ,而oleg.cherednik的答案中忽略了这一点。您最好判断是否需要同步以供参考。

很容易假设List迭代是线程安全的(因为您没有更新列表),但这可能并不总是正确的。 Refer this question and all answers 进行详细讨论。

因此,总结如下-您开始实现线程-通过首先分析某些对象是否在线程之间共享来为类提供安全性。如果对象是共享的,则需要同步对这些对象的读/写(以使其原子化,并且前提是这些对象还不是线程安全的)。如果没有对象共享-它已经是线程安全的。另外,尝试使用已经具有线程安全性的数据结构创建类,这样您就可以减少工作量。

oleg.cherednik的回答也是

java.lang.NullPointerException(NPE)。