Понимаю задумку – есть общий ресурс и важно разделить доступ к нему из разных нитей. Что не укладывается в голове:
1. В теории такая проблема должна быть только со статичными переменными. С полями экземпляров классов такого ведь быть не должно, потому что у каждого экземпляра класса свое значение поля и они не должны путаться. Возможна ситуация, когда мы вкладываем какой-то один экземпляр класса в конструктор разных нитей, как здесь:
public class Program {
public static void main(String[] args) {
CommonResource commonResource= new CommonResource();
for (int i = 1; i < 6; i++){
Thread t = new Thread(new CountThread(commonResource));
t.setName("Thread "+ i);
t.start();
}
}
}
class CommonResource{
int x=0;
}
class CountThread implements Runnable{
CommonResource res;
CountThread(CommonResource res){
this.res=res;
}
public void run(){
synchronized(res){
res.x=1;
for (int i = 1; i < 5; i++){
System.out.printf("%s %d \n", Thread.currentThread().getName(), res.x);
res.x++;
try{
Thread.sleep(100);
}
catch(InterruptedException e){}
}
}
}
}
В этом примере (взят из Метанита) не понимаю, как если в конструкторах new CountThread используется одна и та же переменная commonResource, у которой создается 1 экземпляр класса - как synchronized позволяет на выходе получить 5 строчек с цифрами от 1 до 4. Все нити ведь обращаются к одной переменной, точнее к полю одного единственного экземпляра класса!!! Эта переменная ведь должна расти!!!
2. Не понимаю в принципе логику, когда нужно делать synchronized блок, а когда метод.
3. В этой задаче - почему не подходит такое решение (знаю, что не подходит):
public class Solution {
public static void main(String[] args) {
Person diana = new Person("Diana");
Person igor = new Person("Igor");
diana.start();
igor.start();
}
public static class Person extends Thread { //Человек
public Person(String name) {
super(name);
}
@Override
public void run() {
Iron iron = takeIron();
Clothes clothes = takeClothes();
ironing(iron, clothes);
returnIron();
}
protected Iron takeIron() {
System.out.println("Taking an Iron");
return new Iron();
}
synchronized protected Iron returnIron() {
System.out.println("Returning the Iron");
return new Iron();
}
protected Clothes takeClothes() {
return new Clothes("T-shirt");
}
protected void ironing(Iron iron, Clothes clothes) {
System.out.println(getName() + "'s ironing the " + clothes.name);
}
}
public static class Iron {
} //Утюг
public static class Clothes {//Одежда
String name;
public Clothes(String name) {
this.name = name;
}
}
}
- пожалуйста, поясните, как нужно рассуждать, чтобы решить задачу.
ААААА! Паника((((((((