如果我有一个同步的公共方法和私有方法:
public synchronized void doSomething() {
doSomethingElse()
}
private void doSomethingElse() {
}
Run Code Online (Sandbox Code Playgroud)
我需要同步私有方法吗?
我正在对我不拥有的Java产品进行代码审查.我不是Java专家,但我强烈怀疑这是毫无意义的,并且表明对同步如何工作的基本误解.
synchronized (this) {
this.notify();
}
Run Code Online (Sandbox Code Playgroud)
但我错了,因为Java不是我的主要操场.也许有这样做的原因.如果你可以告诉我开发人员的想法,我将不胜感激.
在Java中实现单例模式时,我想出了这个问题.即使下面列出的示例不是我的真实代码,但与原始代码非常相似.
public class ConnectionFactory{
private static ConnectionFactory instance;
public static synchronized ConnectionFactory getInstance(){
if( instance == null ){
instance = new ConnectionFactory();
}
return instance;
}
private ConnectionFactory(){
// private constructor implementation
}
}
Run Code Online (Sandbox Code Playgroud)
因为我不太确定静态同步方法的行为,所以我从谷歌得到了一些建议 - 在同一个类中没有(或尽可能少)多个静态同步方法.我想在实现静态同步方法时,会使用属于Class对象的锁,这样多个静态同步方法可能会降低系统的性能.
我对吗?或者JVM使用其他机制来实现静态同步方法?如果我必须在类中实现多个静态同步方法,那么最佳实践是什么?
谢谢你们!
亲切的问候!
我需要在我的java类中的一个方法中锁定多个对象.有关示例,请查看以下类:
public class CounterMultiplexer {
private int counter =0;
private int multiPlexer =5;
private Object mutex = new Object();
public void calculate(){
synchronized(mutex){
counter ++;
multiPlexer = multiPlexer*counter;
}
}
public int getCounter(){
return counter;
}
public int getMux(){
return multiPlexer;
}
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我有两个可以通过多个线程访问的资源.这两个资源是counter和multiPlexer属性.正如您在上面的代码中看到的,我使用互斥锁锁定了两个资源.
这种锁定方式是否正确?我是否需要使用嵌套的Synchronized语句来锁定calculate方法中的两个资源?
可能重复:
避免在Java中同步(this)?
这两段代码有什么区别?每个的优点和缺点是什么?
1)
public class Example {
private int value = 0;
public int getNextValue() {
synchronized (this) {
return value++;
}
}
}
Run Code Online (Sandbox Code Playgroud)
2)
public class Example {
private final Object lock = new Object();
private int value = 0;
public int getNextValue() {
synchronized (lock) {
return value++;
}
}
}
Run Code Online (Sandbox Code Playgroud) 通过阅读Java Concurrency in Practice
我可以看到:
要安全地发布对象,必须同时使对象的引用和对象的状态对其他线程可见.正确构造的对象可以通过以下方式安全发布:
但是,我对第二个成语感到困惑.因为volatile只能保证引用对另一个线程可见,但它没有引用的对象构造的同步.那么如何保证可变对象被正确构造,构造该对象的线程被另一个线程中断了?
在Java中,通常认为在未编写的类类型的对象上显式同步是安全的吗?我问这个是因为看起来如果该对象在内部尝试自身同步,那么在另一个尝试使用该对象的非同步方法的内部获取对象监视器的另一个线程与明确获取的线程之间可能存在意外的死锁锁定对象.我从来没有听过或读过任何说这是个坏主意的事情,虽然它似乎可能是.
假设我有一个方法,可以通过两个或多个线程访问,我想让它保证线程安全.
public int getVal(int x, int y, MyClass myObj)
{
int z;
z = getInt(myObj);
return x + y + z;
}
Run Code Online (Sandbox Code Playgroud)
在这里,我认为我们不必同步x + y,因为它们是原始的.
让我们假设getInt(myObj)修改myObj的状态并影响z的值.
因此,我将不得不为该行提供同步,z = getInt(myObj);但仅当两个线程都在'myObj'引用中传递相同的实例时.作为API的编码器,我不知道两个线程是否都会为'myObj'传递相同的实例.在某些情况下,这些线程可能会在"myObj"引用中传递相同的MyClass实例,而在其他情况下,它们可能会在"myObj"引用中传递不同的MyClass实例.
那么,如何确保线路的线程安全z = getInt(myObj)?(当然,我们不希望在传递的实例不同时进行同步,并且只有在传递的实例相同时才需要同步.我很清楚这是无法确定的).
假设MyClass不能成为不可变的,我认为以下可能是一个解决方案.
synchronized(myObj)
{
z = getInt(myObj);
}
Run Code Online (Sandbox Code Playgroud)
这是正确的解决方案吗?并且,我们可以通过其他方式确保线程安全
z = getInt(myObj); (but only in case of different instances)?
Run Code Online (Sandbox Code Playgroud) 我的项目中有A 类和B 类以下的类结构:
class A {
private String id;
private List<B> bs = new ArrayList<B>();
A(String id){
this.id = id;
}
public List<B> getBs(){
return bs;
}
public void setBs(List<B> bs){
this.bs=bs;
}
public void addBs(List<B> bs){
this.bs.addAll(bs);
}
public void addB(B b){
this.bs.add(b);
}
}
class B {
private String id;
private List<String> tags;
B(String id){
this.id = id;
}
public List<String> getTags(){
return tags;
}
public void setTags(List<String> tags){
this.tags = tags;
}
public …Run Code Online (Sandbox Code Playgroud) 我在java中编写了一些多线程代码,并且改变了变量的同步方法,但它没有同步我的代码,我仍然得到随机值.有我的代码:
public class Main {
public static void main(String[] args) throws Exception {
Resource.i = 5;
MyThread myThread = new MyThread();
myThread.setName("one");
MyThread myThread2 = new MyThread();
myThread.start();
myThread2.start();
myThread.join();
myThread2.join();
System.out.println(Resource.i);
}
}
class MyThread extends Thread {
@Override
public void run() {
synMethod();
}
private synchronized void synMethod() {
int i = Resource.i;
if(Thread.currentThread().getName().equals("one")) {
Thread.yield();
}
i++;
Resource.i = i;
}
}
class Resource {
static int i;
}
Run Code Online (Sandbox Code Playgroud)
有时我得7,有时6,但是我已经同步了synMethod,因为据我所知,没有线程应该使用这个方法,而其他一些线程执行这个,所以操作应该是原子的,但它们不是,我不明白为什么?你可以向我解释一下,并回答 - 我该如何解决?