首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >同步方法与ReentrantLock

同步方法与ReentrantLock
EN

Stack Overflow用户
提问于 2016-11-29 19:17:59
回答 1查看 4.7K关注 0票数 4

假设我有一个具有多个线程的服务器,该服务器共享对数据实例的引用。快如,

edit1:更新以提高可读性

代码语言:javascript
复制
public void main() {
 Data data = new Data();
 ReentrantLock rl = new ReentrantLock(true);
 ReadThread t1 = new ReadThread(data, rl);
 UploadThread t2 = new UploadThread(data, rl);
 t1.start(); t2.start();
}

class ReadThread extends Thread {
private Data data;
private ReentrantLock lock;

ReadThread(Data d, ReentrantLock l){ data = d; lock = l; }

     void run(){
        lock.lock();
        try{
        data.put(aString)
        } finally { lock.unlock(); }
     }
}

class UploadThread extends Thread {
private Data data;
private ReentrantLock lock;

UploadThread(Data d, ReentrantLock l){ data = d; lock = l; }

     void run(){
        lock.lock();
        try{
        data.put(aString)
        } finally { lock.unlock(); }
     }
}

最好像上面这样使用锁,还是像下面这样同步put方法,

代码语言:javascript
复制
class Data {
 private LinkedList<String> data = new LinkedList<String>();
 synchronized void put(String x){ data.add(x); }
}

这很粗糙,

我主要是担心并发性。

使用同步方法,我是否正确地假设同步将发生在类的“数据”实例/对象上?因此,一个UploadThread可以调用put过程/方法,另一个ReadThread可以并行地调用。但是,使用ReentrantLock示例,只有一个线程能够在任何时候执行put调用?

如果在"Data“类中,我使LinkedList静态,并使put方法同步和静态,会发生什么情况?哪一种是最好的方法?如果我把事情弄得一成不变,我会失去前女友吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-11-29 19:58:12

在Java中,synchronized部分是可重入的。这意味着单个线程可以按需要多次进入同步部分,但只有在没有其他线程存在的情况下,新线程才能进入。当前在这些部分中的线程已经获得了一个锁,并且只有在离开所有同步部分时才会返回该锁。除了通过方法签名声明synchronized之外,还可以直接对对象调用synchronized。例如,这两种方法将产生相同的效果:

代码语言:javascript
复制
synchronized public void foo() {

}

public void foo() {
    synchronized(this) {

    }
}

ReentrantLock非常类似于synchronized,因为只有一个线程可以一次获得锁。如果一个线程到达一个lock.lock()语句,它将等待到锁被另一个线程解锁。如果线程已经拥有锁,它将继续。在单个同步代码块不够的更复杂的情况下,这可能很有用。

如果..。我让put方法同步和静态?

如果方法是static synchronized,这意味着您正在锁定类本身,而不是类的实例。它是独立于实例synchronized方法而锁定的。

对于您的代码:

这里最简单的方法是将Data对象变成线程安全的对象。如果无法编辑该类的代码,那么一种有效的策略是将对象包装在线程安全的包装器中。

代码语言:javascript
复制
interface Foo {
    void bar();
} 
class UnsafeFoo implements Foo {
    @Override bar() { ... }
}
class ThreadSafeFoo implements Foo {
    Foo foo;
    ThreadSafeFoo(Foo foo) { this.foo = foo; } 
    @Override synchronized bar() { foo.bar(); }
}

Foo unsafe = new UnsafeFoo();
Foo safe = new ThreadSafeFoo(unsafe);
票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40874051

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档