我有一个WeakReference的Collections.synchronizedList,_components;
我写了类似下面的内容,期待编译器抱怨:
public boolean addComponent2(Component e) {
synchronized (_components) {
return _components.add(new WeakReference<Component>(e));
}
}
Run Code Online (Sandbox Code Playgroud)
但编译器非常满意.请注意,List.add()返回TRUE.好吧,从synchronized块的任何退出都会释放锁,但是这个LOOK不是很奇怪吗?它有点像块中的"洞",类似于在循环中使用return.
你会很乐意维护这样的代码吗?
我知道同步方法和同步块之间的区别,但我不确定同步块部分.
假设我有这个代码
class Test {
private int x=0;
private Object lockObject = new Object();
public void incBlock() {
synchronized(lockObject) {
x++;
}
System.out.println("x="+x);
}
public void incThis() { // same as synchronized method
synchronized(this) {
x++;
}
System.out.println("x="+x);
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,使用lockObject和使用它作为锁有什么区别?对我来说似乎是一样的..
当您决定使用synchronized块时,如何确定哪个对象是锁?
Java中的synchronized方法和synchronized块之间有什么区别?
我一直在网上搜索答案,人们似乎对这一个如此不确定:-(
我的看法是两者之间没有区别,除了同步块可能在范围内更加局部化,因此锁定的时间会更短?
如果是静态方法上的Lock,那么Lock是什么?锁定类的含义是什么?
java multithreading synchronization synchronized synchronized-block
例如,这更好吗?
try {
synchronized (bean) {
// Write something
}
} catch (InterruptedException e) {
// Write something
}
Run Code Online (Sandbox Code Playgroud)
或者这更好:
synchronized (bean) {
try {
// Write something
}
catch (InterruptedException e) {
// Write something
}
}
Run Code Online (Sandbox Code Playgroud)
我想知道哪一个是最佳实践.显然考虑到我必须同步try块中的所有代码.我不是在谈论我只能在try中同步部分代码的情况(在这种情况下,我认为在try中包含synch块会更好).我的疑问是关于我要同步所有try块的情况.
我知道
同步代码块时,指定要将哪个对象的锁用作锁,因此您可以使用某些第三方对象作为此代码段的锁.这使您能够在单个对象中拥有多个用于代码同步的锁.
但是,我不明白需要将参数传递给块.因为我是否传递String的实例并不重要,所以作为同步块的一些随机类的实例作为同步块的工作完全无论传递给块的参数如何.
所以我的问题是,如果无论如何同步块阻止两个线程同时进入临界区.那么为什么需要传递一个论点呢?(我的意思是默认获取某些随机对象的锁定).
我希望我正确地提出了我的问题.
我尝试了以下示例,随机参数是同步块.
public class Launcher {
public static void main(String[] args) {
AccountOperations accOps=new AccountOperations();
Thread lucy=new Thread(accOps,"Lucy");
Thread sam=new Thread(accOps,"Sam");
lucy.start();
sam.start();
}
}
Run Code Online (Sandbox Code Playgroud)
使用非静态同步块:
public class AccountOperations implements Runnable{
private Account account = new Account();
public void run(){
for(int i=0;i<5;i++){
makeWithdrawal(10);
}
}
public void makeWithdrawal(int amount){
String str="asd"
synchronized (str /* pass any non-null object the synchronized block works*/) {
if(account.getAmount()>10){
try{
Thread.sleep(5000);
}catch(InterruptedException e){
e.printStackTrace();
}
account.withdraw(amount);
System.out.println(Thread.currentThread().getName()+" has withdrawn 10, …Run Code Online (Sandbox Code Playgroud) 这项练习直接来自Kathy Seirra和Bert Bates的SCJP
同步代码块
在本练习中,我们将尝试同步一段代码.在该代码块中,我们将获得对象的锁定,以便其他线程在代码块执行时无法修改它.我们将创建三个线程,它们都将尝试操作同一个对象.每个线程将输出一个单个字母100次,然后将该字母递增1.我们将使用的对象是StringBuffer.
我们可以在String对象上进行同步,但是一旦创建了字符串就无法修改它们,因此我们无法在不生成新String对象的情况下增加字母.最终输出应该有100个As,100个B和100个C,所有这些都是不间断的.
我为上面的练习编写了下面的课程(而不是100我打印10个字符)
class MySyncBlockTest extends Thread {
StringBuffer sb;
MySyncBlockTest(StringBuffer sb) {
this.sb=sb;
}
public static void main (String args[]) {
StringBuffer sb = new StringBuffer("A");
MySyncBlockTest t1 = new MySyncBlockTest(sb);
MySyncBlockTest t2 = new MySyncBlockTest(sb);
MySyncBlockTest t3 = new MySyncBlockTest(sb);
t1.start();
t2.start();
t3.start();
}
public void run() {
synchronized(this) {
for (int i=0; i<10; i++) {
System.out.print(sb);
}
System.out.println("");
if (sb.charAt(0)=='A')
sb.setCharAt(0, 'B');
else
sb.setCharAt(0, 'C');
} …Run Code Online (Sandbox Code Playgroud) 我的一个应用程序在启动时突然失败,并显示以下错误消息:
java.lang.VerifyError:拒绝类com.sample.BufferManagerImpl,因为编译时验证失败('com.sample.BufferManagerImpl'的声明出现在/data/app/com.sample.myapp-1/base.apk中)
它仅在使用ART虚拟机的设备上失败,但在Dalvik上没有
我试图通过替换一些synchronized块来减少代码中的线程争用AtomicBoolean.
这是一个例子synchronized:
public void toggleCondition() {
synchronized (this.mutex) {
if (this.toggled) {
return;
}
this.toggled = true;
// do other stuff
}
}
Run Code Online (Sandbox Code Playgroud)
替代方案AtomicBoolean:
public void toggleCondition() {
if (!this.condition.getAndSet(true)) {
// do other stuff
}
}
Run Code Online (Sandbox Code Playgroud)
利用AtomicBooleanCAS的属性应该比依赖同步更快,所以我运行了一些微基准测试.
对于10个并发线程和1000000次迭代,AtomicBoolean只比synchronized块快一点.
使用AtomicBoolean:0.0338在toggleCondition()上花费的平均时间(每个线程)
使用synchronized:0.0357在toggleCondition()上花费的平均时间(每个线程)
我知道微基准值得他们值得,但差异不应该更高吗?
我正在阅读JVM规范,试图找出如何正确处理监视器.他们在相关部分中给出的示例如下所示:
0 aload_1 // Push f
1 dup // Duplicate it on the stack
2 astore_2 // Store duplicate in local variable 2
3 monitorenter // Enter the monitor associated with f
4 aload_0 // Holding the monitor, pass this and...
5 invokevirtual #5 // ...call Example.doSomething()V
8 aload_2 // Push local variable 2 (f)
9 monitorexit // Exit the monitor associated with f
10 goto 18 // Complete the method normally
13 astore_3 // In case of …Run Code Online (Sandbox Code Playgroud) 假设我有一个对象如下:
Map<String, String> m = new HashMap<>();
Run Code Online (Sandbox Code Playgroud)
然后我按如下方式同步该对象并更改其引用:
synchronize(m){
m = new HashMap<>();
}
Run Code Online (Sandbox Code Playgroud)
有了这段代码,m 上的锁会发生什么情况?更新 m 代表的新对象是否仍然安全?或者锁本质上是在旧对象上?
java concurrency multithreading synchronized synchronized-block