多线程和锁

时间:2019-05-12 06:17:01

标签: java multithreading

在尝试进入条件之前,我试图了解锁和多线程的工作方式。这是我当前正在测试的代码:

public class tester {
    private static int count = 0;

    public void incrementCount() {
        count++;
    }

    public int getCount() {
        return count;
    }

    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(new testing());
        Thread thread2 = new Thread(new testing());
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
        System.out.println(count);
    }
}

这是实现Runnable的部分:

public class testing implements Runnable {
    Lock lock = new ReentrantLock();
    tester in = new tester();

    public void run() {
        for (int i = 0; i < 1000; i++) {
            lock.lock();
            in.incrementCount();
            lock.unlock();

        }
    }
}

我遇到的问题是我试图在main方法的末尾打印出2000,但是即使使用锁,它也从未真正输出到2000。帮助将不胜感激!

2 个答案:

答案 0 :(得分:2)

  

即使我正在使用锁。

您正在为两个线程中的每个线程使用单独的锁。

如果您希望锁在线程之间进行协调,则它们都需要使用相同的锁实例。否则就没有意义了。

更改为类似

class Testing implements Runnable {
    private final Lock lock;

    // pass in the lock to use via the constructor
    // both threads need to receive the same lock
    Testing(Lock lock){ this.lock = lock; }           

    public void run() {
        for (int i = 0; i < 1000; i++) {
            lock.lock();
            Tester.incrementCount();
            lock.unlock();
        }
    }
}

答案 1 :(得分:1)

锡洛是正确的,但我认为可以用另一种方式解释它。

锁(Lock实现和原始锁)的主要目的是获得对某些数据的互斥访问。 “协议”为:

  • 获取锁定
  • 访问和/或修改数据
  • 释放锁。

假设是,当一个线程持有该锁时,没有其他线程可以访问数据 1

但这仅在锁和数据之间存在一对一关联时才有效。也就是说,您需要获取数据的锁 才能获得独占访问权限。如果您获得了另一组数据的锁,它将无法正常工作。如果您尝试对同一组数据使用多个锁,通常 2 也将不起作用。

在您的示例中,每个线程都有自己的锁,但是只有一个数据正在尝试控制对它们的访问。结果,两个线程可以同时访问和更新数据。


Thilo的答案显示了(一种)解决问题的正确方法。


1-这实际上是线程之间的“契约”。 Java语言不会(也不能)阻止线程在不持有锁的情况下访问和更新“受控”数据。线程必须遵守合同才能实现正确的同步和互斥。

2-通常但并非总是如此。例如,ReadWriteLock提供了一对锁对象,它们一起提供互斥的读写访问权限或共享的只读访问权限。