我试图探索static synchronized method
我得到的理论概念是它获得了对课程的锁定,而不是实例。但是我没能创建一个可以测试它的例子。
这里我创建了要测试的代码,但两个实例同时访问static synchronized method
。
class Demo{
public static synchronized void a(){
System.out.println("A Method " + Thread.currentThread().getName());
}
}
public class StaticSyn{
public static void main(String[] args){
Demo obj = new Demo();
Demo obj2 = new Demo();
Thread one = new Thread(){
@Override
public void run(){
int i=0;
while(i<5){
obj.a();
try{
Thread.sleep(100);
}catch(InterruptedException e){
}
i++;
}
}
};
Thread two = new Thread(new Runnable(){
@Override
public void run(){
int i=0;
while(i<5){
obj2.a();
try{
Thread.sleep(100);
}catch(InterruptedException e){ }
i++;
}
}
});
one.start();
two.start();
}
}
static synchronized
我得到此输出。
A Method Thread-0
A Method Thread-1
A Method Thread-1
A Method Thread-0
A Method Thread-1
A Method Thread-0
A Method Thread-0
A Method Thread-1
A Method Thread-1
A Method Thread-0
没有static
关键字我得到此输出。
A Method Thread-0
A Method Thread-1
A Method Thread-1
A Method Thread-0
A Method Thread-0
A Method Thread-1
A Method Thread-0
A Method Thread-1
A Method Thread-1
A Method Thread-0
那么,问题出在哪里?以及我如何测试只有一个对象正在访问静态同步方法。
答案 0 :(得分:2)
您可以在方法sleep
中添加a()
作为下一个:
public static synchronized void a(){
System.out.println("Before sleep: A Method " + Thread.currentThread().getName());
try{
Thread.sleep(100);
} catch(InterruptedException e){
Thread.currentThread().interrupt();
}
System.out.println("After sleep: A Method " + Thread.currentThread().getName());
}
然后你会看到你不会有2个线程同时执行这个块,就像在下一个输出中一样,实际上你连续两次没有Before sleep
:
Before sleep: A Method Thread-0
After sleep: A Method Thread-0
Before sleep: A Method Thread-1
After sleep: A Method Thread-1
Before sleep: A Method Thread-0
After sleep: A Method Thread-0
Before sleep: A Method Thread-1
After sleep: A Method Thread-1
Before sleep: A Method Thread-0
After sleep: A Method Thread-0
Before sleep: A Method Thread-1
After sleep: A Method Thread-1
Before sleep: A Method Thread-0
After sleep: A Method Thread-0
Before sleep: A Method Thread-1
After sleep: A Method Thread-1
Before sleep: A Method Thread-0
After sleep: A Method Thread-0
Before sleep: A Method Thread-1
After sleep: A Method Thread-1
static synchronized
方法和synchronized
方法有什么区别?
主要区别在于用于同步访问的对象。
<强>静态强>
例如,这样做:
class Demo {
public static synchronized void a() {
// Rest of the method
}
}
等同于:
class Demo {
public static void a() {
synchronized (Demo.class) {
// Rest of the method
}
}
}
换句话说,在static
方法的情况下,它使用表示类本身的对象来同步访问。
非静态
例如,这样做:
class Demo {
public synchronized void a() {
// Rest of the method
}
}
等同于:
class Demo {
public void a() {
synchronized (this) {
// Rest of the method
}
}
}
换句话说,在non static
方法的情况下,它使用类的当前实例来同步访问。
答案 1 :(得分:0)
您需要让a()
方法运行很长时间,以确保方法调用不重叠。这是一种方法:
package com.example;
public class Demo {
public static synchronized void a() {
for (int i = 0; i < 5; i++) {
System.out.println("A Method " + Thread.currentThread().getName());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
final Demo obj = new Demo();
final Demo obj2 = new Demo();
Thread one = new Thread() {
@Override
public void run() {
obj.a(); // same as Demo.run()
}
};
Thread two = new Thread() {
@Override
public void run() {
obj2.a(); // same as Demo.run()
}
};
one.start();
two.start();
}
}