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

Java并发问题-锁和同步方法,java,multithreading,java.util.concurrent,Java,Multithreading,Java.util.concurrent,我正在研究重入锁,并试图将其与同步关联起来。然而,这两个类都给了我意想不到的结果。我希望arrayList的值为0到9。但这两个项目都没有这种价值。请建议。 带锁: package Threads; import java.util.ArrayList; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.Loc

我正在研究重入锁,并试图将其与同步关联起来。然而,这两个类都给了我意想不到的结果。我希望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();
    }
}
包线程;
导入java.util.ArrayList;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.locks.Lock;
导入java.util.concurrent.locks.ReentrantLock;
公共类锁定{
锁定=新的可重入锁定(true);
ArrayList al=新的ArrayList();
静态整数计数=0;
公共空间生产者(){
lock.lock();
计数++;
加上(计数);
系统输出打印项次(al);
试一试{
睡眠(5000);
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}最后{
lock.unlock();
}
//println(“我从这个块中出来:+Thread.currentThread().getName());
}
公众消费者(){
}
公共静态void main(字符串[]args){
//ExecutorService ex=Executors.newCachedThreadPool();
ExecutorService ex=Executors.newFixedThreadPool(10);
对于(int i=0;i<10;i++){
ex.submit(新的可运行(){
@凌驾
公开募捐{
试一试{
《睡眠》(2000年);
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
新锁().producer();
}
});
}
例如关闭();
}
}
与同步:

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();
    }

}
包线程;
导入java.util.ArrayList;
导入java.util.Collections;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
公共类锁定与同步{
ArrayList al=新的ArrayList();
静态整数计数=0;
公共同步无效生成器(){
计数++;
加上(计数);
系统输出打印项次(al);
试一试{
睡眠(5000);
//println(“我从这个块中出来:+Thread.currentThread().getName());
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
公共静态void main(字符串[]args){
//ExecutorService ex=Executors.newCachedThreadPool();
ExecutorService ex=Executors.newFixedThreadPool(10);
对于(int i=0;i<10;i++){
ex.submit(新的可运行(){
@凌驾
公开募捐{
试一试{
《睡眠》(2000年);
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
新的LockwithSynchronize().producer();
}
});
}
例如关闭();
}
}

您的synchronize不保护静态变量-synchonize仅在这样使用时锁定当前
对象的监视器。任何product()调用都不会等待您发布的代码中的任何其他调用。锁定共享的东西——比如说LockWithProducer.class。

这有很多问题

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

由于每次都使用新的
lock with synchronize
lock
,因此实际上没有任何共享锁--每个实例都有自己的锁,它从不与任何其他锁冲突,这意味着
count
变量完全不受保护。您可能会定期收到损坏的
ArrayList
,这是由于在多个线程上调用
add
而没有同步,或者
ConcurrentModificationException
或类似的错误

试试这个:

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();
}
publicstaticvoidmain(字符串[]args){
ExecutorService ex=Executors.newFixedThreadPool(10);
最终锁定生成器=新锁定();

对于(int i=0;iLSO),您到底希望得到什么样的输出?您真的希望每个LockWithSynchronize都有一个列表?还是希望所有线程都输出到一个列表?您得到什么样的输出?