Java中的同步函数

时间:2011-11-24 22:51:21

标签: java multithreading concurrency synchronization

我有一个具有如下同步功能的类:

public synchronized void enqueue(int number) {...}

在我的程序中,我有几个运行的线程都希望在类的特定对象上使用此函数。我想要发生的是线程只是尝试使用该函数,如果它被锁定而不等待它只是跳过运行该函数。

可以使用Java.util.concurency库不使用并仅使用syncronization primatives吗?

不使用并发的限制不是可选的

5 个答案:

答案 0 :(得分:3)

我喜欢AtomicInteger解决方案,但AtomicInteger当然是并发包的一部分。您可以使用以下简单代码遵循相同的原则(效率较低):

private boolean locked = false;

public void enqueue(int number) {
    synchronized (this) {
        if (locked) {
            return;
        }
        locked = true;
    }

    try {
        // Synchronized goodness goes here.
    } finally {
        synchronized (this) {
            locked = false;
        }
    }
}

答案 1 :(得分:0)

我建议使用类似AtomicInteger类的东西,而不是使用任何同步原语来为您的反并发策略利用CAS(比较和交换)操作:

public void enqueue(int number) {
    if (!atomicInteger.compareAndSet(0, 1) {
        return;
    }

    try {
        // Synchronized goodness goes here.
    } finally {
        atomicInteger.set(0);
    }
}

答案 2 :(得分:0)

由于你受到限制,这就是我要做的事情:

创建一个能够告诉它你想要锁定它的类。锁有两种类型:被动锁和主动锁。被动锁将允许无限数量的线程通过。活动锁定将使其仅属于该线程。

当您想要被动锁时,您必须自己注册,并在完成后取消注册。您将等待内部对象,直到完成所有活动锁定。

如果需要主动锁定,则等待所有当前被动锁定未注册。如果当前存在活动锁(使用Thread.currentThread()存储线程引用以查看是否存在),则等待通知。然后,您可以将自己设置为引用线程。取消注册时,如果有等待的活动锁定,请通知其中一个(考虑Set<Thread>注册)。如果没有,请通知所有正在等待的被动锁,并且可以通过。

这里会有很多未解答的问题,我怀疑它是完美的,但这是你正在寻找的大部分......

答案 3 :(得分:0)

可能是您可以同步处理队列的对象。如果其他人使用队列,则入队无效。我有一个编译和运行的例子。非常简单的例子但不漂亮:

    class Queue {
        public void enqueue(int number) {
            // something in this method for demo purposes only 
            try {
                Thread.sleep(100);
            } catch (InterruptedException e){}
            System.out.println(Thread.currentThread().getName()+" done");
        }
    }

    class Demo {
        private static Queue e = new Queue();

        public void enqueue(int number) {
            Queue q = getQueue();
            if (q!=null) {
                q.enqueue(number);
                releaseQueue(q);
            } else {
                // do nothing since the queue is being used
                System.out.println(Thread.currentThread().getName()+" done doing nothing");
            }
        }

        public synchronized Queue getQueue() {
            Queue b = e;
            e = null;
            return b;
        }

        public synchronized void releaseQueue(Queue q) {
            e = q;
        }

        public static void main(String[] args) {
            for (int j = 0; j < 5; j++) {
                Thread t = new Thread(new Runnable() {
                    public void run() {
                        Demo d = new Demo();
                        d.enqueue(5);
                    }
                }, "Thread "+j);
                t.start();
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e){}
            }
        }

    }

答案 4 :(得分:-1)

是您可以通过管理该类中的静态变量或使用“锁定”文本文件来自行实现锁定。

HOWEVER 虽然这种简单的黑客攻击不会非常困难 - 但java.util.concurrency包解决方案会更加简单,而且是一个更好的选择,因为正如您将很快发现的那样将多线程资源构建到应用程序中我们的需求将迅速超出您当前的预期

不要担心整个并发包 - 我发现只需花3分钟来学习如何使用AtomicBoolean或AtomicLong字段就足以以最小的努力实现简单的多线程逻辑。