簡體   English   中英

同步:多個鎖-創建鎖對象?

[英]Synchronization: multiple locks - create lock objects?

一個快速的(我認為)並發問題:我正在Udemy.com上完成多線程課程,而老師講了下面的代碼。 盡管他解釋了這一點,但我仍然不確定為什么要創建lock1lock2對象而不是鎖定list1list2

App.java:

public class App {

    public static void main(String[] args) {
        Worker worker = new Worker();
        worker.main();
    }
}

Worker.java:

import java.util.ArrayList;
import java.util.List;
import java.util.Random;


public class Worker {

    private Random random = new Random();

    private Object lock1 = new Object();
    private Object lock2 = new Object();

    private List<Integer> list1 = new ArrayList<Integer>();
    private List<Integer> list2 = new ArrayList<Integer>();

    public void stageOne() {

        synchronized (lock1) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            list1.add(random.nextInt(100));
        }

    }

    public void stageTwo() {

        synchronized (lock2) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            list2.add(random.nextInt(100));
        }

    }

    public void process() {
        for(int i=0; i<1000; i++) {
            stageOne();
            stageTwo();
        }
    }

    public void main() {
        System.out.println("Starting ...");

        long start = System.currentTimeMillis();

        Thread t1 = new Thread(new Runnable() {
            public void run() {
                process();
            }
        });

        Thread t2 = new Thread(new Runnable() {
            public void run() {
                process();
            }
        });

        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        long end = System.currentTimeMillis();

        System.out.println("Time taken: " + (end - start));
        System.out.println("List1: " + list1.size() + "; List2: " + list2.size());
    }
}

我不認為對的動機在你給的代碼表示,但它通常最好的做法。 但是,相同的最佳實踐也要求鎖定對象也是final

如果有問題的列表是從外部接受的,或者是通過某種方法暴露給外部的,那么單獨的鎖對象的好處就變得更加明顯:將您的鎖暴露給外來代碼永遠不是一個好主意,因為外來代碼可以然后單獨使用它們進行鎖定,從而破壞您自己的使用模式。

如果列表嚴格保密,那么它們的監視器將可用於內部鎖定; 但是,以后對列表上的訪問策略進行更改可能會無意中影響鎖定策略。 因此,從私人鎖開始也可以避免將來出現任何錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM