Java 同时调用静态和非静态方法的线程

Java 同时调用静态和非静态方法的线程,java,multithreading,Java,Multithreading,免责声明:此代码是从 我对它做了一些修改。我想知道如何让线程同时调用synchronized静态和非静态方法。我可以通过将非静态方法包装在synchronized块中使其工作。还有别的办法吗 public class StaticNonStaticSynch { public static void main(String[] args) { final StaticNonStaticTest staticNonStaticTest = new StaticNonSt

免责声明:此代码是从

我对它做了一些修改。我想知道如何让线程同时调用synchronized静态和非静态方法。我可以通过将非静态方法包装在synchronized块中使其工作。还有别的办法吗

public class StaticNonStaticSynch  
{ 
 public static void main(String[] args)  
 { 
      final StaticNonStaticTest staticNonStaticTest = new StaticNonStaticTest(); 
  Runnable runnable1 = new Runnable()  
  { 
   @Override 
   public void run()  
   { 
staticNonStaticTest.nonStaticMethod(); 
   } 
  }; 

  Runnable runnable2 = new Runnable()  
  { 
   @Override 
   public void run()  
   { 
    StaticNonStaticTest.staticMethod(); 
   } 
  }; 

  Thread thread1 = new Thread(runnable1, "First Thread"); 
  Thread thread2 = new Thread(runnable2, "Second Thread"); 

  thread1.start(); 
  thread2.start(); 
 } 
} 

class StaticNonStaticTest 
{ 

 void nonStaticMethod() 
 { 
 //synchronized (StaticNonStaticTest.class){ 
   for(int i=0;i<50;i++) 
   { 
    System.out.println("Non - Static method called by " + Thread.currentThread().getName() +" : = "+i); 
   } 
// } 
 } 
 static synchronized void staticMethod() 
 {  
   for(int i=0;i<50;i++) 
   { 
    System.out.println("Static method called by " + Thread.currentThread().getName() +" : = "+i); 
   } 
 } 
} 
公共类静态非静态同步
{ 
公共静态void main(字符串[]args)
{ 
最终StaticNonStaticTest StaticNonStaticTest=新的StaticNonStaticTest();
Runnable runnable1=新的Runnable()
{ 
@凌驾
公开募捐
{ 
staticnonstatistictest.nonstatisticmethod();
} 
}; 
Runnable runnable2=新的Runnable()
{ 
@凌驾
公开募捐
{ 
StaticNonStaticTest.staticMethod();
} 
}; 
螺纹1=新螺纹(runnable1,“第一个螺纹”);
螺纹2=新螺纹(runnable2,“第二个螺纹”);
thread1.start();
thread2.start();
} 
} 
类静态非静态测试
{ 
void非静态方法()
{ 
//已同步(StaticNonStaticTest.class){

对于(int i=0;i您可以让两个方法在公共锁对象上进行内部同步。否则,在静态方法执行时让实例方法块同步的唯一方法是在类对象上进行同步(正如您在注释行中所做的那样)

同步实例方法在对象实例上同步;同步静态方法在类实例上同步。请注意,如果类有两个实例(例如,来自不同的类装入器),则同步静态方法可能同时执行.你通常会知道这是否发生,因为你必须做大量的工作才能做到

以下是同步公共锁对象上的静态方法和实例方法的一种方法:

class StaticNonStaticTest {
    private static final Object LOCK_OBJECT = new Object();

    void nonStaticMethod() {
        synchronized (LOCK_OBJECT) {
            for (int i=0; i<50; i++) {
                System.out.println("Non - Static method called by "
                  + Thread.currentThread().getName() + " : = " + i);
            }
        }
    }

    static void staticMethod() {
        synchronized (LOCK_OBJECT) {
            for (int i=0; i<50; i++) {
                System.out.println("Static method called by "
                  + Thread.currentThread().getName() +" : = "+i);
            } 
        } 
    }
}
类静态非静态测试{
私有静态最终对象锁_Object=新对象();
void非静态方法(){
已同步(锁定对象){

对于(int i=0;i您可以让两个方法在公共锁对象上进行内部同步。否则,在静态方法执行时让实例方法块同步的唯一方法是在类对象上进行同步(正如您在注释行中所做的那样)

同步实例方法在对象实例上同步;同步静态方法在类实例上同步。请注意,如果类有两个实例(例如,来自不同的类装入器),则同步静态方法可能同时执行.你通常会知道这是否发生,因为你必须做大量的工作才能做到

以下是同步公共锁对象上的静态方法和实例方法的一种方法:

class StaticNonStaticTest {
    private static final Object LOCK_OBJECT = new Object();

    void nonStaticMethod() {
        synchronized (LOCK_OBJECT) {
            for (int i=0; i<50; i++) {
                System.out.println("Non - Static method called by "
                  + Thread.currentThread().getName() + " : = " + i);
            }
        }
    }

    static void staticMethod() {
        synchronized (LOCK_OBJECT) {
            for (int i=0; i<50; i++) {
                System.out.println("Static method called by "
                  + Thread.currentThread().getName() +" : = "+i);
            } 
        } 
    }
}
类静态非静态测试{
私有静态最终对象锁_Object=新对象();
void非静态方法(){
已同步(锁定对象){
对于(int i=0;i请记住:

public class MyClass {

    public synchronized void doSomething() {
        // Do something
    }

    public synchronized static void doSomethingStatic() {
        // Do something static
    }
}
基本上编译为:

public class MyClass {

    public void doSomething() {
        synchronized(this) {
            // Do something
        }
    }

    public static void doSomethingStatic() {
        synchronized(MyClass.class) {
            // Do something static
        }
    }
}
请注意,它们不会在同一事物上同步。若要解决此问题,请创建一个对象,让它们都锁定(称为互斥对象或“互斥对象”):

这应该使得这两个方法中只有一个在多个线程中同时运行

以下几点提示:

  • 始终使用
    已同步(变量)
    处理
    变量
    最终
  • 互斥体
    不一定是严格意义上的互斥体,它可以是一个实际对象。请参见下面的示例
  • 记住方法上的
    synchronized
    修饰符是如何有效实现的。它就像
    this
    MyClass.class
    上的
    synchronized
    块一样
除了具有严格意义上的互斥对象外,您还可以使用
final
的任何字段。例如,在迭代过程中在上同步:

public class MyClass {

    private static final Map<String, String> map = new HashMap<String, String>(); // Java 6
    private static final Map<String, String> map = new HashMap<>(); // Java 7

    public static void put(String k, String v) {
        synchronized(map) {
            map.put(k, v);
        }
    }

    public static void printAll() {
        synchronized(map) {
            for (Entry<String, String> entry : map.entrySet()) {
                System.out.println(entry.getKey() + ":" + entry.getValue());
            }
        }
    }
}
公共类MyClass{
私有静态最终映射=新HashMap();//Java 6
私有静态最终映射=新HashMap();//Java 7
公共静态void put(字符串k、字符串v){
同步(地图){
map.put(k,v);
}
}
公共静态void printAll(){
同步(地图){
for(条目:map.entrySet()){
System.out.println(entry.getKey()+“:”+entry.getValue());
}
}
}
}
这段代码保证您永远不会得到

请记住:

public class MyClass {

    public synchronized void doSomething() {
        // Do something
    }

    public synchronized static void doSomethingStatic() {
        // Do something static
    }
}
基本上编译为:

public class MyClass {

    public void doSomething() {
        synchronized(this) {
            // Do something
        }
    }

    public static void doSomethingStatic() {
        synchronized(MyClass.class) {
            // Do something static
        }
    }
}
请注意,它们不会在同一事物上同步。若要解决此问题,请创建一个对象,让它们都锁定(称为互斥对象或“互斥对象”):

这应该使得这两个方法中只有一个在多个线程中同时运行

以下几点提示:

  • 始终使用
    已同步(变量)
    处理
    变量
    最终
  • 互斥体
    不一定是严格意义上的互斥体,它可以是一个实际对象。请参见下面的示例
  • 记住方法上的
    synchronized
    修饰符是如何有效实现的。它就像
    this
    MyClass.class
    上的
    synchronized
    块一样
除了具有严格意义上的互斥对象外,您还可以使用
final
的任何字段。例如,在迭代过程中在上同步:

public class MyClass {

    private static final Map<String, String> map = new HashMap<String, String>(); // Java 6
    private static final Map<String, String> map = new HashMap<>(); // Java 7

    public static void put(String k, String v) {
        synchronized(map) {
            map.put(k, v);
        }
    }

    public static void printAll() {
        synchronized(map) {
            for (Entry<String, String> entry : map.entrySet()) {
                System.out.println(entry.getKey() + ":" + entry.getValue());
            }
        }
    }
}
公共类MyClass{
私有静态最终映射=新HashMap();//Java 6
私有静态最终映射=新HashMap();//Java 7
公共静态void put(字符串k、字符串v){
同步(地图){
map.put(k,v);
}
}
公共静态void printAll(){
同步(地图){
for(条目:map.entrySet()){
System.out.println(entry.getKey()+“:”+entry.getValue());
}
}
}
}
这段代码保证你永远不会得到一个

怎么可能