Используя это ключевое слово с синхронизированным блоком в Java
У меня есть два потока, которые имеют доступ к объекту. с помощью synchronized (a) я поставляю блокировку на объект a, так что теперь каждый раз в потоке может получить доступ к объекту "a" и изменить его. Если выполнить этот код, мы имеем 1 2. без синхронизированного блока несколько раз получаем 2 2 .(поток t1 получить i и увеличить i, теперь поток t2 получить i и увеличить его, затем поток t1 получить i и напечатать 2, а также поток t2 получить i и напечатать 2), если я верен, почему мы не можем использовать синхронизированный (это) вместо синхронизированного (а)?
public class Foo {
public static void main(String[] args) {
B b =new B();
b.start();
}
}
class B{
A a = new A();
Thread t1 =new Thread(new Runnable(){
public void run(){
synchronized(a){
a.increment();
}
}
});
Thread t2 =new Thread(new Runnable(){
public void run(){
synchronized(a){
a.increment();
}
}
});
public void start(){
t1.start();
t2.start();
}
}
class A{
int i = 0;
public void increment() {
i++;
System.out.println(i);
}
}
2 ответа
Если я правда, почему мы не можем использовать синхронизированный (это) вместо синхронизированного (а)?
Если вы сделали:
public void run() {
synchronized (this) {
a.increment();
}
}
this
в данном случае это экземпляр включающего класса, здесь анонимный объект Runnable, и, поскольку каждый поток имеет свой собственный экземпляр Runnable, ваша синхронизация выполняется на отдельных объектах и не будет работать. Вы должны синхронизировать на B.this
чтобы это работало.
public void run() {
synchronized (B.this) {
a.increment();
}
}
или любой другой уникальный объект, который одинаков для всех блоков синхронизации.
Или, если вы хотите использовать synchronized (this)
затем используйте один Runnable:
class B {
A a = new A();
Runnable r = new Runnable() {
public void run() {
synchronized (this) {
a.increment();
}
};
};
public void start() {
// t1.start();
// t2.start();
new Thread(r).start();
new Thread(r).start();
}
}
Другой подход:
Сделать метод increment
синхронизированный
public class Foo {
public static void main(String[] args) {
new B().start();
}
}
class B {
A a = new A();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
a.increment();
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
a.increment();
}
});
public void start() {
t1.start();
t2.start();
}
}
class A {
int i = 0;
public synchronized void increment() { // <<<<<<<<
i++;
System.out.println(i);
}
}