我有4种方法(m1,m2,m3和m4一类).方法m1,m2并m3有synchronized方法.另外,我有4个线程t1,t2,t3和t4分别.
如果t1访问m1方法(synchronized方法),可以同时进行t2线程访问m2方法(synchronized方法)吗?如果不是t2的状态是什么?
这样做,即ConcurrentHashMap(所有非retreival操作put(),remove()等等)需要被包裹在一个synchronized(this)块?我知道所有这些操作都是线程安全的,所以这样做有什么好处/需要吗?使用的唯一操作是put()和remove().
protected final Map<String, String> mapDataStore = new ConcurrentHashMap<String, String>();
public void updateDataStore(final String key, final String value) {
...
synchronized (this) {
mapDataStore.put(key, value);
}
...
}
Run Code Online (Sandbox Code Playgroud) 有这个等待声明:
public final native void wait(long timeout) throws InterruptedException;
Run Code Online (Sandbox Code Playgroud)
它可以通过InterruptedException或超时退出,或者因为在另一个线程中调用Notify/NotifyAll方法,Exception很容易捕获但是...
有什么方法可以知道退出原因是超时还是通知?
编辑:
这是一种可行的方法,(虽然我不喜欢)
long tBefore=System.currentTimeMillis();
wait(TIMEOUT);
if ((System.currentTimeMillis() - tBefore) > TIMEOUT)
{
//timeout
}
Run Code Online (Sandbox Code Playgroud) 参考这个答案,我想知道这是对的吗?
@synchronized不会使任何代码"线程安全"
当我试图找到支持此声明的任何文档或链接时,没有成功.
任何评论和/或答案将在此受到赞赏.
为了更好的螺纹安全性,我们可以使用其他工具,这对我来说是已知的.
我有超类Point和synchronized方法draw().如果我覆盖它们中的方法或者我必须总是写它,Point继承的子类synchronized是否会继承draw()?
所以我正在测试synchronized关键字.这是我尝试的一个例子:
public class MyTest {
static int i = 0;
public static void main(String[] args) {
new Thread(t1).start();
new Thread(t2).start();
}
private static void countMe(String name){
i++;
System.out.println("Current Counter is: " + i + ", updated by: " + name);
}
private static Runnable t1 = new Runnable() {
public void run() {
try{
for(int i=0; i<5; i++){
countMe("t1");
}
} catch (Exception e){}
}
};
private static Runnable t2 = new Runnable() {
public void run() { …Run Code Online (Sandbox Code Playgroud) 可能有人告诉我是否可以从一个@synchronized街区内返回?
例如:
- (id)methodThatReturnsSomething:(BOOL)bDoIt
{
@synchronized(self) {
if(!bDoIt) return nil;
...
}
}
Run Code Online (Sandbox Code Playgroud)
或者我应该先解锁块(使用NSLock代替)?
我正在使用Disruptor框架及其.NET平台端口,并发现了一个有趣的案例.可能是我完全错过了一些东西所以我正在寻找全能社区的帮助.
long iterations = 500*1000*1000;
long testValue = 1;
//.NET 4.0. Release build. Mean time - 26 secs;
object lockObject = new object();
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
lock (lockObject)
{
testValue++;
}
}
sw.Stop();
//Java 6.25. Default JVM params. Mean time - 17 secs.
Object lock = new Object();
long start = System.currentTimeMillis();
for (int i = 0; i < iterations; i++)
{
synchronized (lock)
{ …Run Code Online (Sandbox Code Playgroud) 这个问题的关键是要说明Java没有像我预期的那样工作.
您希望以下代码如何表现?
public class SynchTester {
private static SynchTester synchTester;
public synchronized static SynchTester getSynchTester(){
if(synchTester==null){
synchTester = new SynchTester();
}
return synchTester;
}
private SynchTester() {
SynchTester myTester = getSynchTester();
}
public static void main(String[] args) {
SynchTester tester = SynchTester.getSynchTester();
}
}
Run Code Online (Sandbox Code Playgroud)
我希望它挂起一个死锁等待递归完成,但它会抛出StackOverflow.显然,synchronized不会阻止访问同一个线程.
这是一个错误吗?
我在StackOverflow的评论中读到了这个:
但是如果你想要安全,你可以在@PostConstruct [方法]的末尾添加简单的synchronized(this){}
[注意变量不易变化]
我认为只有当写入和读取都是在块中执行或者至少读取是易失性时才会强制执行synchronized.
引用的句子是否正确?空synchronized(this) {}块是否将当前方法中更改的所有变量刷新为"一般可见"内存?
请考虑一些场景
如果第二个线程从不调用锁定this怎么办?(假设第二个线程在其他方法中读取).请记住,问题是:刷新对其他线程的更改,而不是给其他线程一种方式(同步)来轮询原始线程所做的更改.在Spring @PostConstruct上下文中,很可能在其他方法中没有同步- 正如原始评论所说.
是仅在另一个线程的第二次和后续调用中强制执行的更改的内存可见性?(请记住,这个同步块是我们方法中的最后一个调用) - 这会将这种同步方式标记为非常糟糕的做法(第一次调用中的陈旧值)
synchronized ×10
java ×8
objective-c ×2
c# ×1
cocoa ×1
concurrency ×1
inheritance ×1
ios ×1
locking ×1
macos ×1
memory-model ×1
notify ×1
performance ×1
recursion ×1
volatile ×1
wait ×1