Here is my simple code for 2 threads to alternate in printing 2 different numbers. Thread A prints 1 and Thread B prints 2. Both should alternate amongst themselves to print 1,2,1,2,1,2,1,2,....and so on.
Now I see in the below program we are getting <1,2>,<1,2> combination,...and so on for 5 times only.
Looks like both threads have the same variables which is being shared. But i is a local variable. How it i shared
public class MyThread extends Thread{
int numToPrint;
Turn turn;
MyThread(int n, Turn turn)
{
this.numToPrint=n;
this.turn=turn;
}
public void run() {
for (int i=0;i<10;i++) {
if(turn.t==numToPrint) {
System.out.println(numToPrint);
if(numToPrint==1)
turn.t=2;
else
turn.t=1;
turn.doNotify();
}
else
{
turn.doWait();
}
}
}
}
public class Main {
public static void main(String[] args) {
Turn t=new Turn();
MyThread t1=new MyThread(1,t);
t1.start();
MyThread t2=new MyThread(2,t);
t2.start();
}
}
Related
I have two threads named t1 and t2. They only make an addition to total integer variable. But the variable total isn't shared among these threads. I want to use same total variable in both the t1 and t2 threads. How can I do that?
My Adder runnable class:
public class Adder implements Runnable{
int a;
int total;
public Adder(int a) {
this.a=a;
total = 0;
}
public int getTotal() {
return total;
}
#Override
public void run() {
total = total+a;
}
}
My Main class:
public class Main {
public static void main(String[] args) {
Adder adder1=new Adder(2);
Adder adder2= new Adder(7);
Thread t1= new Thread(adder1);
Thread t2= new Thread(adder2);
thread1.start();
try {
thread1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
try {
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(adder1.getTotal()); //prints 7 (But it should print 9)
System.out.println(adder2.getTotal()); //prints 2 (But it should print 9)
}
}
Both print statements should give 9 but they give 7 and 2 respectively (because the total variable doesn't isn't by t1 and t2).
The easy way out would be to make total static so it's shared between all Adder instances.
Note that such a simplistic approach would be sufficient for the main method you shared here (which doesn't really run anything in parallel, since each thread is joined right after being started). For a thread-safe solution, you'll need to protect the addition, e.g., by using an AtomicInteger:
public class Adder implements Runnable {
int a;
static AtomicInteger total = new AtomicInteger(0);
public Adder(int a) {
this.a = a;
}
public int getTotal() {
return total.get();
}
#Override
public void run() {
// return value is ignored
total.addAndGet(a);
}
}
how to run threads after other threads finished, let say i have 3 java class (Cls1 and Cls2 implements runnable, and I use sleep to know which statements are run first), this is my code :
public class Master {
#SuppressWarnings("unused")
public static void main(String[] args) {
//loop1
for(int i=1; i<=2; i++) {
Cls1 c1 = new Cls1();
}
//Here i want to wait until the thread loop1 is finished, what to do?
//loop2
for(int j=1; j<=2; j++) {
Cls2 c2 = new Cls2();
}
}
}
public class Cls1 implements Runnable{
Thread myThread;
Cls1() {
myThread = new Thread(this, "");
myThread.start();
}
#Override
public void run() {
System.out.println("hello1");
TimeUnit.SECONDS.sleep(3);
System.out.println("hello2");
}
}
public class Cls2 implements Runnable{
Thread myThread;
Cls2() {
myThread = new Thread(this, "");
myThread.start();
}
#Override
public void run() {
System.out.println("hello3");
TimeUnit.SECONDS.sleep(3);
System.out.println("hello4");
}
}
And this is output my code :
hello1
hello1
hello3
hello3
hello2
hello2
hello4
hello4
And this is the output I expect:
hello1
hello1
hello2
hello2
hello3
hello3
hello4
hello4
What should I do ?
You could try something like that:
#SuppressWarnings("unused")
public static void main(String[] args) {
Thread threads[] = new Thread[2];
//loop1
for(int i=1; i<=2; i++) {
threads[i-1] = new Cls1();
}
for (Thread thread: threads) {
thread.join();
}
//loop2
for(int j=1; j<=2; j++) {
Cls2 c2 = new Cls2();
}
}
UPDATE: Make Cls1 a subclass of Thread:
public class Cls1 extends Thread {
Cls1() {
start();
}
#Override
public void run() {
System.out.println("hello1");
TimeUnit.SECONDS.sleep(3);
System.out.println("hello2");
}
}
If you want to wait for the thread to finish, call the join method.
To run thread one after another, it needs to be synchronized.
wait, notify and notifyAll ..all of these can be used.
If you don't synchronize it, then it doesn't guarantee the order of output what you desire to be produced.
So for this we have to take one variable "flag" and and synchronize threads one by one as below:
If value of flag=1, then it is class A's turn to print.
If value of flag=2, then it is class B's turn to print.
If value of flag=3, then it is class C's turn to print.
This is my code which i tried but my main class is not there because i don't know how to use that one
//first thread
class firstthread extends Thread
{
public void run(){
for(int i=0;i<1000;i++)
{
System.out.println(i);
}}
}
//second thread
class secondthread extends Thread
{
public void run(){
for(int i=0;i<1000;i++)
{
System.out.println(i);
}}
}
First overide the run method and then create the object of thread class in main()
and call start method.
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
new Thread() {
public void run() {
for(int y=0;y<1000;y++)
{
System.out.println(y);
}
};
}.start();
}
}
Whatever you have written is incomplete code, to create a thread you need to extend Thread class or implement Runnable interface and then override its public void run() method.
To create a thread you need to override the method public void run
Then to start the threads you need to call its start() method.
A simple complete example
class MyThread extends Thread {
String name;
public void run(){
for(int i=0;i<1000;i++) {
System.out.println("Thread name :: "+name+" : "i);
}
}
}
class Main{
public static void main(String args[]){
MyThread t1 = new MyThread();
t1.name = "Thread ONE";
MyThread t2 = new MyThread();
t2.name = "Thread TWO";
MyThread t3 = new MyThread();
t3.name = "Thread THREE";
t1.start();
t2.start();
t3.start();
}
}
You can't just put some code in your class body.
You need a method to have the code in, the method being run() in case of thread.
Instead of copy-pasting the code, I'll point you to the official documentation where you can find some examples.
Sample program given below. Since there is no synchronization code, there output is mixed from the three threads
public class ThreadTest implements Runnable{
#Override
public void run() {
System.out.print(Thread.currentThread().getId() + ": ");
for(int i=0;i<100;i++)
System.out.print(i + ", ");
System.out.println();
}
public static void main(String[] args) {
for(int i=0;i<3;i++){
new Thread(new ThreadTest()).start();
}
}
}
This is what the output should look like:
Each column should be printed using a separate thread. So in this case there will be 3 threads, one that prints the numbers, an other that prints their squares and an other that prints their cubes.
Following everyone's comments i have written this code.
public class PrintThread
{
private static final int LIMIT=10;
final static Queue<Integer> number=new LinkedList();
final static Queue<Integer> square=new LinkedList();
final static Queue<Integer> cube=new LinkedList();
public static void main(String[] args)
{
System.out.println("Number\tSquare\tCube");
for(int i=0;i<LIMIT;i++)
number.offer(i);
new Thread(new Runnable(){
public void run(){
for(int i=0;i<LIMIT;i++)
square.offer(i*i);
}
}).start();
new Thread(new Runnable(){
public void run(){
for(int i=0;i<LIMIT;i++)
cube.offer(i*i*i);
}
}).start();
for(int i=0;i<LIMIT;i++){
System.out.println(number.poll()+"\t"+square.poll()+"\t"+cube.poll());
}
}
}
Now this still does not ensure the correct output.
I want the main thread to print only after the other two threads have finished filling the queues. How do I do that?
Actually 3 thread printing on the same line one after another conveys the meaning of sequential execution. I do not think threads are useful here.
But if you mean only Calculation needs to be done using different threads, then you can use join() on the threads. You can use one loop to initialize and start the threads and in the second loop join() them. (Note that if you join() in the same loop, then the threads execute as sequentially.)
After the second loop you can print the formatted result.
Try This :
class RunnableDemo implements Runnable {
private Thread t;
private String threadName;
static int i=0;
RunnableDemo( String name){
threadName = name;
}
public void run() {
i=i+1;
System.out.print(""+i+"\t\t"+(i*i)+"\t");
}
public void start ()
{
System.out.print("\t"+(i*i*i+"\n"));
}
}
class TestThread {
public static void main(String args[])
{
System.out.print("Number Square Cube\n");
RunnableDemo [] r1=new RunnableDemo[10];
for(int i=1;i<10;i++)
{
r1[i]=new RunnableDemo(""+i);
r1[i].run();
r1[i].start();
}
}
}
Please see the program below
public class TestVolatile implements Runnable {
public static volatile int counter;
public static String lock = "lock";
public static void main(String[] args) {
Thread t1 = new Thread(new TestVolatile(),"Thread-1");
Thread t2 = new Thread(new TestVolatile(),"Thread-2");
t1.start();
t2.start();
}
public void run() {
synchronized(this) {
System.out.println(Thread.currentThread()+"-"+counter);
counter++;
}
}
}
If I run this program multiple times, I get 3 different results.
first is
Thread[Thread-1,5,main]-0
Thread[Thread-2,5,main]-0
second is
Thread[Thread-1,5,main]-0
Thread[Thread-2,5,main]-1
third is
Thread[Thread-1,5,main]-1
Thread[Thread-2,5,main]-0
But if change the lock object from "this" to "lock", I get 2 different results
first is
Thread[Thread-1,5,main]-0
Thread[Thread-2,5,main]-1
second is
Thread[Thread-1,5,main]-1
Thread[Thread-2,5,main]-0
My assumption when writing the program was that in either case the "counter" should never come 0 in both statements.
Can somebody explain?
You create two TestVolatile objects. The "this" keyword refers to the TestVolatile object being run in the thread. Thus you do not synchronize on the same object in the first example.
If you change the code like this, then the first example starts working:
public static void main(String[] args) {
TestVolatile testVolatile = new TestVolatile();
Thread t1 = new Thread(testVolatile,"Thread-1");
Thread t2 = new Thread(testVolatile,"Thread-2");
t1.start();
t2.start();
}
It's probably not what you're looking for, but if you want to avoid the use of synchronized and volatile, you should use an instance of AtomicInteger:
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/AtomicInteger.html
Use the getAndIncrement method to show the same behavior as in your example.
public class TestVolatile implements Runnable {
public static AtomicInteger counter = new AtomicInteger();
public static void main(String[] args) {
Thread t1 = new Thread(new TestVolatile(),"Thread-1");
Thread t2 = new Thread(new TestVolatile(),"Thread-2");
t1.start();
t2.start();
}
public void run() {
System.out.println(Thread.currentThread() + " - " + counter.getAndIncrement());
}
}