синхронизированый блок кода может быть выполнен только одним потоком одновременно !!!
public class DemoClass{
public synchronized void demoMethod(){
//other thread safe code
}
}
В статическом методе, синхронизация будет осуществляться по классу.
public class DemoClass{
public static synchronized void demoMethod(){
//other thread safe code
}
}
опасная штука !!!
Не синхронизируйте по не финальному (no final) полю, потому что ссылка, на не финальное поле может измениться в любое время, а затем другой поток может получить синхронизацию на разных объектах и уже не будет никакой синхронизации вообще. Лучше всего использовать класс String, который уже неизменяемый и финальный.
public class DemoClass{
private final Object lock = new Object();
public void demoMethod(){
synchronized (lock) {
//other thread safe code
}
}
}
class MyClass {
private static String name1 = "Оля";
private static String name2 = "Лена";
public static void swap() {
synchronized (MyClass.class) {
String s = name1;
name1 = name2;
name2 = s;
}
}
}
public class BadSynchronized {
public static void main(String[] args) throws Exception{
Resource resource = new Resource(8);
MyThread thread1 = new MyThread(resource);
thread1.setName("firstThread");
MyThread thread2 = new MyThread(resource);
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(resource.getI());
}
}
class MyThread extends Thread{
private final Resource resource;
MyThread(Resource res) { resource=res; }
@Override
public void run() {
resource.incrementI();
}
}
class Resource {
private int i;
/* synchronized */ void incrementI(){
int iLocal = this.i;
if(Thread.currentThread().getName().equals("firstThread")){
Thread.yield();
}
iLocal++;
this.i =iLocal;
}
Resource(int i) { this.i = i; }
int getI() { return i; }
}