thread and creating object - java

I am trying to learn about thread and find some examples in the internet. This is a java class that output "hello, world" every 3 seconds. But I have a feeling that the part about creating a Runable object is redundant.
Instead of writing
Runnable r = new Runnable(){ public void run(){...some actions...}};
Can I put the method run() somewhere else for easy reading?
This is what I have:
public class TickTock extends Thread {
public static void main (String[] arg){
Runnable r = new Runnable(){
public void run(){
try{
while (true) {
Thread.sleep(3000);
System.out.println("Hello, world!");
}
} catch (InterruptedException iex) {
System.err.println("Message printer interrupted");
}
}
};
Thread thr = new Thread(r);
thr.start();
}
And this is what I want to accomplish
public static void main (String[] arg){
Runnable r = new Runnable() //so no run() method here,
//but where should I put run()
Thread thr = new Thread(r);
thr.start();
}

Can I put the method run() somewhere else for easy reading?
Yes you could create your own runnable like this
public class CustomRunnable implements Runnable{
// put run here
}
and then
Runnable r = new CustomRunnable () ;
Thread thr = new Thread(r);

From the Java threads tutorial, you can use a slightly different style:
public class HelloRunnable implements Runnable {
public void run() {
System.out.println("Hello from a thread!");
}
public static void main(String args[]) {
(new Thread(new HelloRunnable())).start();
}
}

Just make your anonymous Runnable class an inner static class, like so:
public class TickTock {
public static void main (String[] arg){
Thread thr = new Thread(new MyRunnable());
thr.start();
}
private static class MyRunnable implements Runnable {
public void run(){
try{
while (true) {
Thread.sleep(3000);
System.out.println("Hello, world!");
}
} catch (InterruptedException iex) {
System.err.println("Message printer interrupted");
}
}
}
}
Or since TickTock already extends Thread in your example code, you can just override its run method:
public class TickTock extends Thread {
public static void main (String[] arg){
Thread thr = new TickTock();
thr.start();
}
#Override
public void run(){
try{
while (true) {
Thread.sleep(3000);
System.out.println("Hello, world!");
}
} catch (InterruptedException iex) {
System.err.println("Message printer interrupted");
}
}
}

Related

How to check for functionalty with multiple threads working without synchronization

Consider this code:
public class test2 {
public static void main(String[] args) throws Exception{
Thread t1 = new Thread(new Runnable() {
public void run() {
for(int i = 0; i<1000000; i++) {
}
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
Out.println("Counter" +" "+ i);
}
});
t1.start();
t2.start();
}
}
This code is susposed to complete this task:
Implement a program in which a thread increments a counter (static field) 1000000 times. Another thread should immediately output the same counter without waiting for the end of the first thread.
Is my code right? The reason why I am asking is because the output is always 0,and I am not sure if that is right.I'm confused as how to check for functionalty of a code when there is no synchronization in play.
The problem is that your code is missing the required static field (e.g. i in the code given below).
class Main {
// Counter
static int i = 0;
public static void main(String[] args) throws Exception {
Thread t1 = new Thread(new Runnable() {
public void run() {
for (i = 0; i < 1000000; i++) {
}
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
System.out.println("Counter" + " " + i);
}
});
t1.start();
t2.start();
}
}
Output:
Counter 8588

Run method not working inside ForkJoinTask

I have a sub class of RecursiveTask which contains a Runnable object and should execute it.The problem is that the code inside the run method never gets reached although I use ForkJoinPool.execute in order to not block the main thread.
public class test {
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
Display.getDefault().syncExec(new Runnable() {
#Override
public void run() {
System.out.println("lo");
}
});
}
};
ATLockTask t = new ATLockTask();
t.runnable = r;
new ForkJoinPool().execute(t);
}
}
public class ATLockTask extends RecursiveTask<Object>{
public Runnable runnable;
#Override
protected Object compute() {
try {
runnable.run();
} catch (Exception e) {
logger.catching(e);
}
return null;
}
}

Threads not running at same time

I made a concurrency class to test out threads. since I wanted to find out the best way to run threads at the same time.
I am surprised by my results:
test
test
Othertest
test
Othertest
test
test
test
The results I expected were for the threads to come back randomly yet they seem to come back consistently in the same order! Does anyone know why? Does this mean that they are not running concurrently? How might I go about getting them to run at the same time?
Here is my code:
public class ThreadTest {
public static void main(String args[]) throws InterruptedException
{
new Thread(new ThreadTest().test()).start();
new Thread(new ThreadTest().test()).start();
new Thread(new ThreadTest().otherTest()).start();
new Thread(new ThreadTest().test()).start();
new Thread(new ThreadTest().otherTest()).start();
new Thread(new ThreadTest().test()).start();
new Thread(new ThreadTest().test()).start();
new Thread(new ThreadTest().test()).start();
}
public Runnable test() throws InterruptedException{
Thread.sleep((long) (Math.random()*1000));
System.out.println("test");
return null;
}
public Runnable otherTest() throws InterruptedException{
Thread.sleep((long) (Math.random()*1000));
System.out.println("Othertest");
return null;
}
}
The Thread constructor accepts a Runnable on which the Thread will eventually execute the run() method. Right now you aren't returning a Runnable object. you are returning null. So the execution you do in your test() and otherTest() methods is executed synchronously.
All your execution happens in one thread. This
new Thread(new ThreadTest().test()).start();
executes test(), sleeps for a second, prints "test" and returns null. The start() call doesn't do anything because the Runnable is null. This continues for each other call you do.
You need to put everything in your test() and otherTest() methods inside a Runnable#run() method. For example
new Thread(new Runnable() {
public void run() {
Thread.sleep((long) (Math.random()*1000));
System.out.println("test");
}
}).start();
Consider the source code of the run() method of Thread class, which is executed when start() is called
#Override
public void run() {
if (target != null) {
target.run();
}
}
Where target is the Runnable reference you pass in the constructor. Obviously, if it is null, it won't do anything.
I think you might have better luck with this:
public class ThreadTest {
public static void main(String args[]) throws InterruptedException
{
new Thread(test).start();
new Thread(test).start();
new Thread(otherTest).start();
new Thread(test).start();
new Thread(otherTest).start();
new Thread(test).start();
new Thread(test).start();
new Thread(test).start();
}
public static Runnable test = new Runnable() {
#Override
public void run() {
try {
Thread.sleep((long) (Math.random()*1000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("test");
}
};
public static Runnable otherTest = new Runnable() {
#Override
public void run(){
try {
Thread.sleep((long) (Math.random()*1000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Othertest");
}
};
}
The idea is to pass an instance of Runnable as an argument to the Thread constructor. You are not really doing that, because test() and otherTest() are both returning null. The above code shows one way of running the threads in the way that I'm guessing you want. Other approaches are certainly possible.
You need to implement your test and otherTest methods as Runnable implementations. Like so:
private static class Test implements Runnable {
#Override
public void run() {
try {
Thread.sleep((long) (Math.random()*1000));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
System.out.println("test");
}
}
private static class OtherTest implements Runnable {
#Override
public void run() {
try {
Thread.sleep((long) (Math.random()*1000));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
System.out.println("Othertest");
}
}
public static void main(String args[]) {
new Thread(new Test()).start();
new Thread(new Test()).start();
new Thread(new OtherTest()).start();
new Thread(new Test()).start();
new Thread(new OtherTest()).start();
new Thread(new Test()).start();
new Thread(new Test()).start();
new Thread(new Test()).start();
}
You could, of course, try to reduce the duplication a little:
private enum Runnables implements Runnable {
TEST {
#Override
public void run() {
if (!sleep()) return;
System.out.println("test");
}
},
OTHER_TEST {
#Override
public void run() {
if (!sleep()) return;
System.out.println("Othertest");
}
};
static boolean sleep() {
try {
Thread.sleep((long) (Math.random()*1000));
return true;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
}
}
}
public static void main(String args[]) {
new Thread(Runnables.TEST).start();
new Thread(Runnables.TEST).start();
new Thread(Runnables.OTHER_TEST).start();
new Thread(Runnables.TEST).start();
new Thread(Runnables.OTHER_TEST).start();
new Thread(Runnables.TEST).start();
new Thread(Runnables.TEST).start();
new Thread(Runnables.TEST).start();
}
Your Thread implementation is WRONG.
You should either implement Runnable and implement run() method or
you should extend Thread class and override run() method.
What is happening is that your test() method or otherTest() is being called just as any method calls. And since you don't have any run() method your Thread.start() wont simply run anything.
Try changing your method like below.
public Runnable test() {
return new Runnable() {
#Override
public void run() {
try {
Thread.sleep((long) (Math.random() * 1000));
System.out.println("test");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}
public Runnable otherTest() {
System.out.println("Othertest");
return new Runnable() {
#Override
public void run() {
try {
Thread.sleep((long) (Math.random() * 1000));
System.out.println("Othertest");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}

Java Thread argument

On my way to learn threads, this is working as intended
public class Game implements Runnable{
//FIELDS
private Thread t1;
boolean running;
//METHODS
public void start(){
running = true;
t1 = new Thread(this);
t1.start();
}
public void run(){
while (running){
System.out.println("runnin");
try {
Thread.sleep(17);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
And then, when I change the thread argument into
t1=new Thread (new Game());
The program doesn't enter the run method anymore.
Shouldn't they be the same? What should be the other way to substitute the "this" keyword?
EDIT: I'm calling the start method from another class.
Even setting the running variable to true after the instance has been created, it remains false:
public void start(){
t1 = new Thread(new Game());
running = true;
t1.start();
}
It enters the run() method, but it immediately returns from it, because the run method loops while running is true.
When calling new Game(), you're constructing a new different instance of Game, whose running field is false. So the loop doesn't loop at all:
public void start(){
running = true; // set this.running to true
t1 = new Thread(new Game()); // construct a new Game. This new Game has another, different running field, whose value is false
t1.start(); // start the thread, which doesn't do anything since running is false
}
Change it to
public void start(){
Game newGame = new Game();
newGame.running = true;
t1 = new Thread(newGame);
t1.start();
}
and it will do what you expect.
Not the same, in the first case if you call start() you'll create a new thread and start it, but when you use new Thread(new Game()) you need to call start() on the new thread.
Try this:
t1=new Thread (new Game());
t1.start();
It enters the run method but the variable 'running' is initialized to false for the new object created using new Game(). Hence, it does not print anything on the console.
If you want to create a thread for another instance of the object , you could try the following :
public class Game implements Runnable{
//FIELDS
private Thread t1;
boolean running;
//Constructor to set the running boolean
public Game(boolean running)
{
this.running = running;
}
//METHODS
public void start(){
running = true;
t1 = new Thread(new Game(running));
t1.start();
}
public void run(){
while (running){
System.out.println("runnin");
try {
Thread.sleep(17);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Game implements Runnable{
//FIELDS
private Thread t1;
boolean running;
//METHODS
public void start(){
running = true;
t1 = new Thread(new Game());
t1.start();
}
public void run(){
running=true;
while (running){
System.out.println("runnin");
try {
Thread.sleep(17);
}
catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
class another{
public static void main(String s[]){
Game t=new Game();
t.start();
}
}

java : anonymous class

In java this is valid
new Thread(new Runnable()
{
public void run()
{
for(int i=0;i<5;i++)
System.out.println("From anonymous:"+i);
}
}
).start();
But this is not :
Thread t=new Thread(new Runnable()
{
public void run()
{
for(int i=0;i<5;i++)
System.out.println("From anonymous:"+i);
}
}
).start();
can I achieve it with anonymous class? If yes then How
Your code does not work, because it wants to assign the result of the start() method to the variable t. You can do it like so:
Thread t=new Thread(new Runnable()
{
public void run()
{
for(int i=0;i<5;i++)
System.out.println("From anonymous:"+i);
}
}
);
t.start();
Also, in this case you don't need to use Runnable interface because is implemented by the Thread class.
new Thread() {
#Override
public void run() {
for(int i=0;i<5;i++)
System.out.println("From anonymous:"+i);
}
}.start();
One thing to note here is that the start method of Thread returns void. This is why you cannot assign it to a variable.

Categories