so as I mentioned their is a second way of creating a thread and that's to use the
runnable interface and the advantage of using that is that it only requires us to
implement a single method wondering can you guess what the name of that
method would be for using the runnable interface well very similar to the
previous way of creating threads we need to implement the run method
so instead of implementing the run method of a class that sub classes
thread we can have any class implements runnable interface and then all we have
to do is add run method to that class of course will then want to
write the code in the run method to execute on a thread that we created
but we'll get to that in a minute so first let's create a new class is going
to implement the runnable interface
go ahead and do that and call the class.....and this time we are going to do a
implements instead of an extends....
....and you can see its complaining because it was saying it must be declared abstract
or implement the abstract method run so we obviously need to do just that we're
going to override or implement that method
so come down here to implement the method which is going to be run
we're going to use another color lets use red for this one so....
.....
.....so we go back to main now
so to run this code on it a new thread we create an instance of the thread class
not a subclass but this time we pass an instance of the my runnable class to
the thread constructor and we can call the threads instances start method just
like we did before
so let's add this code just before the second output here so we're on line
20 so....
....and this time we pass a parameter of the new object which we
create by typing....
so we have now created a new thread based on the my runnable class that
we just created a short while ago
then from there we can type...
so if we run that we get hello from my runnables implementation of run which
obviously was in red which we selected for that class so just when creating
threads by subclassing the thread class
we can also have an anonymous class implements runnable and pass an instance
of it to the thread constructor
so let's change the code that we just write on line 20 to do something like
that so I'm going to.....
....and let's create anonymous class
so do that by putting.....and then we can override so I can do
an override and notice how its come up with com.timbuchalka.myrunnable
so it knows where overriding that particular run
select that
close off the brace and instead of the super.run need another bracket we can leave
the my runnable thread.start their first of all if we do that and run that
notice how we still get the same output because we use super.run
so its running the run method from the my runnable class so we close that down and
instead if we get rid of the super you put something like.....
....
....when we do
that we should see that we get the output from the anonymous classes this time
because we have overridden the run method hello from the anonymous class
implementation of run
so question now you may have is why should we use runnable vs sub classing
the thread class in other words which you know when should you be using the way
well most of the time developers use the runnable way of doing things
now the reason is that - it's more convenient and
there's also many methods in the Java API that when a runnable for instance
passed to them
for example since the introduction of lambda expressions it's become even more
convenient to use anonymous runnable instances
so when we have a choice because we're not calling a method that requires one
or the other
there isn't really a right or wrong answer but most developers use a runnable because
it's more flexible so that would be my recommendation is to consider doing that
but when we read code written by others
you'll probably see that more often than not that we're using a runnable version
so one thing we haven't mentioned is that a thread will terminate when it
returns from its run method either implicitly because it reaches the
methods end or explicitly because it executes a return state now a common
mistake when creating and running threads is to call the threads instance run
method instead of the start method
so remember that we have to implement the run method but we don't call it
directly
the jvm
actually call that for us what happens if we make this mistake well our
application won't crash but instead of running the code in the run method on a
new thread the code is going to be run on the same thread that called
the run method that sounds a little bit confusing but lets see this in action
another good thing that we can do is we can set the name of the thread by using
the set name method
let's do that for the thread that we created earlier to distinguish should
from another so we know exactly where our code is running so i will change the
another thread here in line 12 and let's set it to another name so...
.....will call that something like....
....just so it's clear and you will see why shortly
and if we go back to the another thread class hello from another thread but
instead of putting from another thread lets change this and put...
....return the name of the current thread
that's being executing or being executed
so if we run the code now back in main you can see hello from another thread
because we set the another thread instance to set name to another thread
there that's doing is we thought it would it's creating and running the code
in that thread so if we close this down but if we make the common mistake now of
calling the run method directly rather than start method will see something
different pop-ups so will change now on line 14 .start to .run
....and then we run it you can see we've got an entirely different result
we've got hello from main so clearly its now not running in the same thread
it's running on the main thread which the main method is actually running on
so that's a very important reason why you don't want to be calling the run
method directly what you want to be called the start method instead let's
change that back now to start
run it again and we should see the blue output is now running which it is on the
other thread
so now that we know how to create and start threads let's look at - what else
we can do with threads when they're running now we can ask them to sleep or
to stop executing for a specific amount of time now you might want to do that to
give other threads the opportunity to run and you might also want the thread to
do something every time a specific amount of time has passed
for example we might want to write something to file every 15 seconds or
we might want to check for data and requested every two seconds
we might also want to thread to sleep when we know that it's gotta wait for another
thread to do something and we know that the other thread and only does it
every 10 seconds for example
so what we could do is put the first thread to sleep for 10 seconds rather
than having it continued to run we know it's going to be at least ten seconds
before it gets any results from the second thread so that all sounds a
little bit like hocus-pocus let's go back to the another thread and put some
code in practice and we going to put some code in the run method for the another
thread so let's add a try block and get it to sleep for 3 seconds so i'm going to type....
....and notice how the input the arguments looking for
is in milliseconds so three seconds will be three thousand milliseconds
we need to catch the exception here which is interrupted exception which the
exception we need to catch and we're using a thread.sleep and i'm going to
put that message there...
...because that will be executed if another thread did just that
then after that we can put in some message here to say
....
ok so you can see we've done their we've added a try catch and we've got the
thread or told the thread to sleep for three seconds and the exceptionally
will only thrown
if there are another thread did wake us up so if that's the case we're printing out a
message just to indicate that that doesn't happen we come down here after
three seconds have elapsed to say that we are now awake
so to see this let's just have a look at main we're gonna run main and just watch
the output when we run this you notice that it printed the initial message and that's
because we had the initial message message going back to our
another thread the first message printed immediately then there was a pause there for
three seconds and then it finally came back and said three seconds have passed
and i'm awake and just out of interest we just go back and have a look
where we added the .sleep show that briefly before sleep has
got two options their we got the first method we used was just had a
parameter of milliseconds and we use that for 3,000 but the overloaded method
also accepts the milliseconds but also in nanoseconds so that seconds an
hour it's gonna add two together to determine what the sleeping interval is
we want to be a bit more precise in other words in our case we just used the first
method and specify exactly three seconds or three thousand milliseconds
so as i alluded to it's possible for our thread to wake up prematurely
because another thread interrupts 'it which we talking about in a moment
and of course when that happens as i mentioned the interrupted exception is
thrown you know if the thread isn't interrupted as you saw it woke up after 3
seconds and then print the line about being awake and that worked
obviously because at this stage none of the other threads we created has got
got any code that interrupts this thread and so of course we didn't get the
exceptions thrown
it's important to note that it is never guaranteed that the thread will sleep for
the interval that was specified it could be interrupted just as we discussed also the
jvm has to call the underlying operating system to put the thread to sleep and
it's possible that the operating system may not support the granularity that is
asking for so for example it may not support nano seconds
so its really operating system dependent and operating system and JVM
independent as to how long it will be again as you saw there was clearly a
delayed their and if i run it again
see the first mention is output and we wait for three seconds and we'll see the
second come on the screen after the three seconds had elapsed
so just before we finish this video let's talk a bit more about interrupts
so we interrupt a thread when we want it to stop what it was doing and to do
something else
no more often than not when you do that you need interrupt a thread because we
want it to terminate
so as an example suppose we've got a thread that is monitoring a buffer for data
that another thread is fetching
so when the other thread determines that there are will never by any more data to
fetch for whatever reason we can interrupt the monitoring thread and then it will
terminate
so there's two ways for threads to notice that they've been interrupted the
first ways to catch the interrupted exception and we're at the
code for that in the run method for the another thread class we saw that will
be throw within the sleep method there when the run method doesn't call any
methods that thorwn interrupted exception it should call the interrupted method
periodically to check whether it's been interrupted and that method will return true when
another thread has interrupted it or has interrupted it but how does one thread
interrupt another when it calls the interrupt method on the thread instance
that it wants to interrupt
now of course that means that it will need a reference to the thread instance to be
able to do that to be able to call the interrupt method on the other thread so
we're gonna end the video here in the next video what we're going to do is we're
gonna modify our code to have
one of our other threads interrupt the another thread instance when it's
sleeping just to see how that works
so let's work on that in the next video