Java并发问题 - 锁和同步方法



我正在处理RE进入锁,并试图将其与同步相关联。但是,这两个课程都给我带来了意外的结果。我希望阵列列表具有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变量完全不受保护。而且,由于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,而您的期望发生了:您非常快速地产生十个线程,每个线程都等待了两秒钟,然后才尝试调用producer()。一个线程获取锁,而另一个则锁定。锁定锁的一个然后用锁等待五秒钟,然后退出,此时下一个线程获得锁,等待五秒钟,然后退出等。因此,这将需要接近一分钟的时间才能运行。<<。/p>

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

您的同步不保护静态变量 - 同步时仅锁定当前this对象的监视器。没有product()调用将在您发布的代码中等待任何其他。锁定共享的东西 - 例如lockwithproducer.class。

最新更新