Пример сна не снимает блокировку, а ожидание делает
Здесь есть два класса:
- Main : Содержит основной метод и два потока.
Singleton : это одноэлементный класс с двумя статическими методами getInstance () и getInstance (логическое isWait).
public class Main {
private static Singleton singletonA = null;
private static Singleton singletonB = null;
public static void main(String[] args) throws InterruptedException {
Thread threadA = new Thread() {
@Override
public void run() {
singletonA = Singleton.getInstance(true);
}
};
Thread threadB = new Thread() {
@Override
public void run() {
singletonB = Singleton.getInstance();
while (singletonA == null) {
System.out.println("SingletonA still null");
}
if (singletonA == singletonB) {
System.out.println("Both singleton are same");
} else {
System.out.println("Both singleton are not same");
}
}
};
threadA.start();
threadB.start();
}
}
и
public class Singleton {
private static Singleton _instance;
public static Singleton getInstance() {
if (_instance == null) {
synchronized (Singleton.class) {
if (_instance == null)
_instance = new Singleton();
}
}
return _instance;
}
public static Singleton getInstance(boolean isWait) {
if (_instance == null) {
synchronized (Singleton.class) {
if (_instance == null) {
if (isWait) {
try {
// Singleton.class.wait(500);//Using wait
Thread.sleep(500);// Using Sleep
System.out.println("_instance :"
+ String.valueOf(_instance));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
_instance = new Singleton();
}
}
}
return _instance;
}
}
Теперь, запустив этот пример, вы получите вывод ниже:
_instance :null
Both singleton are same
Здесь экземпляры Singleton, созданные threadA и threadB, одинаковы. Это означает, что threadB ожидает снаружи, пока threadA не снимет свою блокировку.
Теперь измените Singleton.java, комментируя Thread.sleep (500); метод и раскомментирование Singleton.class.wait (500); , Здесь из-за Singleton.class.wait (500); метод threadA снимет все блокировки получения и перейдет в состояние «Runnable», threadB получит изменение для входа в синхронизированный блок.
Теперь запустите снова:
SingletonA still null
SingletonA still null
SingletonA still null
_instance :com.omt.sleepwait.Singleton@10c042ab
SingletonA still null
SingletonA still null
SingletonA still null
Both singleton are not same
Здесь экземпляры Singleton, созданные threadA и threadB, НЕ одинаковы, потому что threadB получил изменение для входа в синхронизированный блок и через 500 миллисекунд threadA начал с последней позиции и создал еще один объект Singleton.