2

向量包含同步方法,而 ArrayLists 不包含。当数据被 >1 个线程访问和修改时,这些同步方法有助于防止数据损坏。

有人可以为我更详细地解释一下吗?Vectors 包含同步方法是什么意思?这些方法是否包含控制多线程访问数据的锁定和解锁的内部锁?有人可以提供一些使用向量(与 ArrayList 相比)可以防止数据损坏并进一步阐明问题或数据结构和同步问题的示例吗?

感谢您的时间和帮助。

4

2 回答 2

3

Vectors 包含同步方法是什么意思?

这些方法已标记为synchronized

这些方法是否包含控制多线程访问数据的锁定和解锁的内部锁?

不,尽管关键字在方法上,但锁定的是对象,而不是方法。没有办法锁定这样的方法。

有人可以提供一些使用向量(与 ArrayList 相比)可以防止数据损坏并进一步阐明问题或数据结构和同步问题的示例吗?

有很多例子。最简单的就是增加一个数字。假设你有两个线程递增一个数字(例如集合的大小),你可以没有同步。

Thread1: read size e.g. 0
Thread1: increment size
Thread1: write size e.g. 1
Thread2: read size e.g. 1
Thread2: increment size
Thread2: write size e.g. 2

但是,由于线程可以按任何顺序执行操作(因为这是线程的全部内容),您也可以拥有

Thread1: read size e.g. 0
Thread2: read size e.g. 0
Thread1: increment size
Thread2: increment size
Thread1: write size e.g. 1
Thread2: write size e.g. 1

因此,即使两个线程增加了计数器,它也是不正确的,因为它们的动作不协调。这就是同步为您所做的。

于 2013-01-31T15:56:13.847 回答
0

哈哈。8岁的问题。我一直在寻找答案,但后来通过在线学习自己创建了一个 Demo。这就是我的理解:您可以在要成为线程安全的对象的方法上使用同步关键字,或者您可以在要使用该对象的任何地方编写同步的 objName。这是一个例子,以防它帮助任何人。这里的 SyncData 是我创建同步对象(数据)的类。

class SyncData {
    synchronized public void print() {
//      public void print() {
        for(int i=1; i<=5; i++) {
            System.out.println("SyncData: print() : "  + Thread.currentThread().getName() + " => " + i);
            try {
                Thread.sleep(1000);
            } catch(InterruptedException excep) {
                System.out.println(excep.getMessage());
            }
        }
    }
}

public class SynchronizedDemo {

    static class SyncChildThread extends Thread {
        SyncData data;
        public SyncChildThread(SyncData data) {
            this.data = data;
        }
        @Override
        public void run() {     
//          synchronized(data) { //alternative way
//              data.print();
//          }
            data.print();
        }
    }

    public static void main(String[] args) {
        //dummy data, which will be shared among multiple threads
        SyncData data = new SyncData();
        SyncChildThread threadOne, threadTwo;
        threadOne = new SyncChildThread(data);
        threadOne.setName("Thread-1");
        threadTwo = new SyncChildThread(data);
        threadTwo.setName("Thread-2");
        threadOne.start();
        threadTwo.start();
    }
}

同步输出将是:

SyncData: print() : Thread-1 => 1
SyncData: print() : Thread-1 => 2
SyncData: print() : Thread-1 => 3
SyncData: print() : Thread-1 => 4
SyncData: print() : Thread-1 => 5
SyncData: print() : Thread-2 => 1
SyncData: print() : Thread-2 => 2
SyncData: print() : Thread-2 => 3
SyncData: print() : Thread-2 => 4
SyncData: print() : Thread-2 => 5

如果您删除同步,那么任何线程都可以随时访问该对象(同时访问)。对象数据非同步访问的输出:

 AsyncData: print() : Thread-1 => 1
AsyncData: print() : Thread-2 => 1
AsyncData: print() : Thread-1 => 2
AsyncData: print() : Thread-2 => 2
AsyncData: print() : Thread-1 => 3
AsyncData: print() : Thread-2 => 3
AsyncData: print() : Thread-1 => 4
AsyncData: print() : Thread-2 => 4
AsyncData: print() : Thread-1 => 5
AsyncData: print() : Thread-2 => 5
于 2021-07-15T16:21:51.330 回答