gpt4 book ai didi

Java 并发问题 - Locks 和 Synchronize 方法

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:43:45 26 4
gpt4 key购买 nike

我正在研究可重入锁并试图将其与 Synchronize 相关联。然而,这两个类(class)都给了我意想不到的结果。我希望 arrayList 有 0 到 9。但是这两个程序都没有这个值。请建议。带锁:

package Threads;

import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Locking {

Lock lock = new ReentrantLock(true);
ArrayList<Integer> al = new ArrayList<Integer>();
static int count = 0;

public void producer() {
lock.lock();
count++;
al.add(count);
System.out.println(al);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
// System.out.println("I came out of this block:"+Thread.currentThread().getName());
}

public void consumer() {
}

public static void main(String[] args) {
// ExecutorService ex= Executors.newCachedThreadPool();
ExecutorService ex = Executors.newFixedThreadPool(10);

for (int i = 0; i < 10; i++) {
ex.submit(new Runnable() {

@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new Locking().producer();
}

});
}
ex.shutdown();
}
}

同步:

package Threads;

import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class LockwithSynchronize {

ArrayList<Integer> al = new ArrayList<Integer>();
static int count = 0;

public synchronized void producer() {
count++;
al.add(count);
System.out.println(al);
try {
Thread.sleep(5000);
// System.out.println("I came out of this block:"+Thread.currentThread().getName());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public static void main(String[] args) {
// ExecutorService ex= Executors.newCachedThreadPool();
ExecutorService ex = Executors.newFixedThreadPool(10);

for (int i = 0; i < 10; i++) {
ex.submit(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new LockwithSynchronize().producer();
}
});
}
ex.shutdown();
}

}

最佳答案

这有很多问题。

首先,您期望它包含 0..9,但是您在 al.add(count) 之前调用了 count++,这意味着您实际上应该期望 1.. 10.

由于您每次都使用新的 LockWithSynchronizeLocking,因此实际上没有任何共享锁——每个实例都有自己的锁,不会发生冲突使用任何其他锁,这意味着您的 count 变量完全不 protected 。由于 add 在没有同步的情况下在多个线程上被调用,或者 ConcurrentModificationException 或类似情况,您可能会定期收到损坏的 ArrayList

试试这个:

public static void main(String [] args){

ExecutorService ex= Executors.newFixedThreadPool(10);

final Locking producer = new Locking();

for (int i=0; i<10;i++)
{
ex.submit(new Runnable(){

@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
producer.producer();
}

});
}

ex.shutdown();
}

请注意,我们不是每次都使用新的 Locking,而是重用同一个实例,现在您期望的事情发生了:您很快产生了 10 个线程,每个线程等待两秒钟尝试调用 producer()。一个线程获得锁,而其他九个线程阻塞。获得锁的线程在退出前等待锁五秒钟,此时下一个线程获得锁,等待五秒钟,然后退出,等等。所以这将花费将近一分钟的时间来运行。

类似的修改也修复了另一个。

关于Java 并发问题 - Locks 和 Synchronize 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30109725/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com