<<并发编程实践>>学习笔记之什么叫锁

之前对并发了解的很少,觉得如果程序存在竞争条件,就直接加一个Synchronized就可以解决。发现越多很多源代码之后,发现别人加锁并不是简简单单的在方法上面加一个synchroized这么简单,先上一段代码.
public List<String> lists = Collections
			.synchronizedList(new ArrayList<String>());

	public synchronized boolean listIfAbsent(String str) {
		boolean ifAbsent = lists.contains(str);
		if (!ifAbsent) {
			lists.add(str);
		}
		return ifAbsent;
	}

	public boolean listIfAbsent1(String str) {
		synchronized (lists) {
			boolean ifAbsent = lists.contains(str);
			if (!ifAbsent) {
				lists.add(str);
			}
			return ifAbsent;
		}

	}
       public static void main(String[] args) {
		final Test t = new Test();
		new Thread() {
			public void run() {

				if (!t.lists.contains("a")) {
					t.lists.add("a");
				}
				if (!t.lists.contains("b")) {
					t.lists.add("b");
				}
				// t.lists.set(0, "chenliang");
				System.out.println(t.lists);
			}
		}.start();

		t.listIfAbsent1("a");
		// t.listIfAbsent("b");

	}


这里面有2个方法listIfAbsent和listIfAbsent1,一个应该算是悲观锁,还有一个是只是对list加锁,我之前以为只要对this加锁,该对象的所有的数据域都应该被保护,即使数据域全部被expose,但是经过测试,发现我错了,即使是同样的一个Test对象,当线程A调用listIfAbsent,线程B执行
t.lists.add("a"),这时候发生什么?我之前的理解就是,线程B是不能修改线程list中的数据域的。但事实上,结果并非如此,数据已经被破坏,导致线程会出现过期的数据。
这说明我根本没有理解什么叫锁。
事实上,锁就是对象的一个属性,一个Object对象都有对应的锁属性。我们对Test t这个对象加锁,但是他并不会去检查别的线程是否修改public lists属性。
我的理解就是,加锁的地方只是在方法上,但是这个Test t本身不代表锁。其他的线程仍然可以通过t去访问它其他的共有成员变量,就像这个LIST.如果是多个线程去调用这个上锁的方法的时候,才会出现互斥。

你可能感兴趣的:(锁)