package com.codegym.task.task23.task2311;
/*
Repeating threads
*/
public class Solution {
public final String name;
public final String food;
public final String sound;
public Solution(String name, String food, String sound) {
this.name = name;
this.food = food;
this.sound = sound;
}
public void eat() {
System.out.println(name + ": Mmmmm, " + food);
}
public void play() {
System.out.println(name + ": " + sound + " " + sound);
}
public void sleep(long milliseconds) {
System.out.println(name + ": Zzzzzzz..." + (milliseconds / 1000) + " s");
}
public void live() throws InterruptedException {
Thread thread = new Thread() {
public void run() {
try {
someActions();
} catch (Exception e) {
e.printStackTrace();
}
}
private void someActions() throws InterruptedException {
eat();
play();
Solution.this.sleep(1000);
}
};
thread.start();
thread.join();
}
public static void main(String[] args) throws InterruptedException {
new Solution("Amigo", "beef", "knock").live();
}
}
So if line 43 only calls sleep(1000);, only eat() and play() get executed.
Then if you change it to what it is now, all 3 get executed.
Why do only the first 2 get executed in the first when all 3 are the same, and why does only sleep need to have Solution.this. before it?
Passed validation but don't understand why
Under discussion
Comments (8)
- Popular
- New
- Old
You must be signed in to leave a comment
Brandon Horvatic
29 October 2019, 15:59
So if line 43 only calls sleep(1000);, only eat() and play() get executed.
Then if you change it to what it is now, all 3 get executed.
Why do only the first 2 get executed in the first when all 3 are the same, and why does only sleep need to have Solution.this. before it?
0
Guadalupe Gagnon
29 October 2019, 16:33
It's because sleep is a method that is part of the Thread class.
At line 31 you are creating a new anonymous class that extends thread which means all of the included methods of thread are included in the class. Because sleep is standard method that means it is in scope of this class when it is called at line 43. What the task wants you to do is call the sleep method that is part of the solution class and not part of the thread class, which is what you did by using its full qualified name.
If you used Solution.sleep() you would get an error of trying to use a method in a static context; also this.sleep() would still point to the Thread.sleep() method. Solution.this.sleep() is the correct way to point to the sleep method in the Solution class of the current object (meaning not statically).
+19
Brandon Horvatic
29 October 2019, 16:58
Okay that makes perfect sense, thank you for the explanation!
+1
Johannes
3 May 2020, 05:52
Thanks for the explanation: I am confused (and slightly irritated, at that ;)
(1) Thread has no eat() or play() methods. So the "compiler" understands that I'm calling the local (Solution) instance's methods for these. So now when it comes to the sleep() method, it knows there're TWO methods called sleep(). One belongs to Solution (is local) and the other one belongs to the Thread class (the two which I can clearly distinguish between by using "this" for my local sleep() method, or thread.sleep() for the Thread class. So it makes no sense to me ?
Obviously I understand classes little enough so far....
Another question: why the HELL do I want to complex my code and do the line "Thread thread = new Thread" and further down "start" and "join" the thread ? I am just instantiating a new Solution class instance ? I could simply say: Solution sol1 = new Solution("Amigo","beef","knock"); ?
And then sol1.live();
It would print the same thing. Now they're just confusing me by throwing thread into the picture ?
0
Johannes
3 May 2020, 05:57
Guada, to add onto my above comment: Removing Thread would be much easier. Creating a new instance of Solution, is also a new "thread", and can run and execute code on it's own. What am I missing ? See below code that works and gives the same result:
public class Solution {
public final String name;
public final String food;
public final String sound;
public Solution(String name, String food, String sound) {
this.name = name;
this.food = food;
this.sound = sound;
}
public void eat() {
System.out.println(name + ": Mmmmm, " + food);
}
public void play() {
System.out.println(name + ": " + sound + " " + sound);
}
public void sleep(long milliseconds) {
System.out.println(name + ": Zzzzzzz..." + (milliseconds / 1000) + " s");
}
public void live() throws InterruptedException {
//Thread thread = new Thread() {
// public void run() {
try {
someActions();
} catch (Exception e) {
e.printStackTrace();
}
// }
}
public void someActions() throws InterruptedException {
eat();
play();
sleep(1000);
}
//thread.start();
//thread.join();
//}
public static void main(String[] args) throws InterruptedException {
new Solution("Amigo", "beef", "knock").live();
}
}
0
Guadalupe Gagnon
4 May 2020, 16:39
As a professional programmer, in the real world, you will be tasked to figure out the most logical and effective way to solve a problem. That is why you will be paid. Now with this task it is important to understand that, as a student, you will be given problems like this that are meant to teach concepts of OOP and how the program executes its code more so than just rewriting the problem. The problem with the code you shared above is that by removing the thread and creating a method the task has fundamentally changed.
The task is designed to have you call the correct "sleep" method from within the anonymous thread class with the problem being that originally it was calling the "sleep" method that was part of the Thread class.
+3
Guadalupe Gagnon
4 May 2020, 16:42
Here is some code that duplicates the same issue as the task, but with classes I defined so all the code is seen:
+1
Guadalupe Gagnon
4 May 2020, 16:52
In this bit of code, starting in main, just creates a LivingBeing object then calls createHuman(). Moving to that method it creates a Human and calls the doAction() method, between lines 24-27 inclusive. Everything works as expected.
Then it creates an anonymous class from Human to override the doAction method, lines 32-38, to use the eat and sleep methods inside the LivingBeing class, lines 43 and 47 (sort of like the problem in the task). This is where a problem occurs because it is still calling the Human classes eat and sleep method, as evidenced by the output. You can change lines 35 and 36 to include LivingBeing.this.eat() and LivingBeing.this.sleep() and the output will change to reflect using the correct eat and sleep methods.
0