I'm writing a program that starts 1000 threads, each thread adds 1 to a variable sum. here's the code:
public class Test1 implements Runnable{
public Test1( ) {
}
public void run() {
Sum.sum++;
}
public static void main(String[] args) {
//Sum s = new Sum();
for (int i = 0; i < 1000; i++) {
Thread t = new Thread(new Test1());
try {
t.start();
t.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Sum.getSum());
}
}
public class Sum {
static int sum;
public Sum() {
sum = 0;
}
public static int getSum() {
return sum;
}
public static void setSum(int sum) {
sum = sum;
}
}
Is there a way that creates an instance of the Sum class, then each thread adds 1 to the same instance of the Sum class? I mean not using a static method or variable.
public class Test1 implements Runnable{
Sum s = null;
public Test1(Sum s) {
this.s = s;
}
public void run() {
s.sum++;
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Sum s = new Sum();
for (int i = 0; i < 1000; i++) {
Thread t = new Thread(new Test1(s));
t.start();
}
System.out.println(s.getSum());
}
}
class Sum {
int sum;
public Sum() {
sum = 0;
}
public int getSum() {
return sum;
}
public void setSum(int sum) {
sum = sum;
}
}
Important notes :
1 - sleep() is static, so it acts on the current running thread, so if you meant to sleep thread t, the correct way to do it is as in the answer
2- System.out.println(s.getSum()); isn't guaranteed to run after all threads finish .... If you want to do so, use ExecutorService
3- do your synchronized add() method instead of accessing the variable directly .... here it wont matter much, but in real life example, you might encounter race condition
Related
Trying to make a simple multi-threaded programme where it prints Factorial series where each number is printed by different Thread and at the end I am giving a report of which number printed by which thread.I have got the desired output but somehow my program is not terminating.
Constraint: I am not allowed to use Concurrent Package
import java.util.ArrayList;
import java.util.Scanner;
class Report {
private long factorial;
private String threadName;
private int activeThreads;
public Report(long factorial, String threadName, int activeThreads) {
this.factorial = factorial;
this.threadName = threadName;
this.activeThreads = activeThreads;
}
public long getFactorial() {
return factorial;
}
public String getThreadName() {
return threadName;
}
public int getActiveThreads() {
return activeThreads;
}
public void setActiveThreads(int activeThreads) {
this.activeThreads = activeThreads;
}
}
public class Factorial implements Runnable {
public static ArrayList<Report> report = new ArrayList<Report>();
private static int count;
public static void main(String[] args) throws InterruptedException {
Scanner in = new Scanner(System.in);
System.out.print("N: ");
int n = in.nextInt();
count = n;
Factorial f = new Factorial();
f.series(n);
Thread.sleep(1000);
// Series
for(Report r : report) {
if(r.getFactorial() == 1) {
System.out.print(r.getFactorial());
}
else {
System.out.print(r.getFactorial() + "*");
}
}
System.out.println();
// Report
for(Report r : report) {
System.out.println(r.getFactorial() + " printed by " + r.getThreadName() + " " + r.getActiveThreads());
}
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
System.out.println("In Main");
in.close();
}
public void series(int n) throws InterruptedException {
for(int i=0;i<n;i++) {
Thread t = new Thread(new Factorial());
t.start();
}
}
public synchronized void generate() {
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
report.add(new Report(count--, Thread.currentThread().getName(), threadGroup.activeCount()));
notifyAll();
System.out.println("In generate" + threadGroup.activeCount());
}
#Override
public void run() {
generate();
synchronized (this) {
try {
wait();
}
catch(Exception e) {
e.printStackTrace();
}
}
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
System.out.println("In Run" + threadGroup.activeCount());
}
public static int getCount() {
return count;
}
public static void setCount(int count) {
Factorial.count = count;
}
}
Although I know that we can kill the threads using .stop() but I think it's not recommended.
To make synchronization effective (synchronized, wait, notify), you have to use the same instance.
In series, you create a new Factorial instance on each loop, making every thread to wait indefinitely.
public void series(int n) throws InterruptedException {
for(int i=0;i<n;i++) {
// Thread t = new Thread(new Factorial()); // creates an new instance
Thread t = new Thread(this);
t.start();
}
}
In the run method, you first call notifyAll() (through generate), and then wait.
The last created thread will wait after all the others are done.
One way or another, this last thread has to be notified.
It could be right after the sleep call, with:
synchronized(f) {
f.notify();
}
or maybe with a dedicated synchronized method.
Hi I am trying to print even and odd using two threads namedly EvenThread and OddThread, some times I am getting correct result and some times not, could any one please help me.
package com.java8;
public class EvenOddExample {
public static synchronized void print(int i,String name){
System.out.println(i+"--->"+name);
}
public static void main(String[] args) throws InterruptedException {
EvenThread e= new EvenThread();
e.start();
OddThread o=new OddThread();
o.start();
}
public static class EvenThread extends Thread{
public void run() {
for(int i=0;i<10;i++){
if(i%2==0){
print(i,"Even");
}else{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public static class OddThread extends Thread{
#Override
public void run() {
for(int i=1;i<10;i++){
if(i%2!=0){
print(i,"Odd");
}else{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
You need some signaling between the two threads. Putting synchronized on the print method simply guarantees, that only one thread can enter the method at a time. To put your threads into order Object.wait() and Object.notify{All}() methods can be used.
Actually this is some kind of the Sender-Receiver Synchronization Problem. Based on the example of the problem described here (Please read this page in order to understand how this synchronization works) I adapted your code. Additionally I used ExecutorService and Callable instead of extending Thread, which is bad-practice:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class EvenOddExample {
private static boolean evensTurn = true;
private static Object monitor = new Object();
public static void print(int i, String name) {
System.out.println(i + "--->" + name);
}
public static void main(String[] args) throws InterruptedException {
final ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(new EvenCallable());
executorService.submit(new OddCallable());
executorService.shutdown();
}
public static class EvenCallable implements Callable<Void> {
#Override
public Void call() throws InterruptedException {
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
synchronized (monitor) {
while (!evensTurn) { // not your turn?
monitor.wait(); // wait for monitor in a loop to handle spurious wakeups
}
print(i, "Even");
evensTurn = false; // next odd needs to run
monitor.notifyAll(); // wakeup the odd thread
}
} else {
Thread.sleep(1000);
}
}
return null;
}
}
public static class OddCallable implements Callable<Void> {
#Override
public Void call() throws InterruptedException {
for (int i = 1; i < 10; i++) {
if (i % 2 != 0) {
synchronized (monitor) {
while (evensTurn) {
monitor.wait();
}
print(i, "Odd");
evensTurn = true;
monitor.notifyAll();
}
} else {
Thread.sleep(1000);
}
}
return null;
}
}
}
synchronized is used to lock the access of another thread, when the locked object is free, it does not guarantee which is next called thread. You can use semaphore to make inter-thread communication:
private static Semaphore[] semaphores = {new Semaphore(0), new Semaphore(1)};
static void print(int i, String name) {
try {
semaphores[(i + 1) % 2].acquire();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println(i + "--->" + name);
semaphores[i % 2].release();
}
public class EvenOddPrinter {
static boolean flag = true;
public static void main(String[] args) {
class Odd implements Runnable {
#Override
public void run() {
for (int i = 1; i <= 10;) {
if (EvenOddPrinter.flag) {
System.out.println(i + "--->odd");
i += 2;
EvenOddPrinter.flag = !EvenOddPrinter.flag;
}
}
}
}
class Even implements Runnable {
#Override
public void run() {
for (int i = 2; i <= 10;) {
if (!EvenOddPrinter.flag) {
System.out.println(i + "---->even");
i += 2;
EvenOddPrinter.flag = !EvenOddPrinter.flag;
}
}
}
}
Runnable odd = new Even();
Runnable even = new Odd();
Thread t1 = new Thread(odd, "Odd");
Thread t2 = new Thread(even, "Even");
t1.start();
t2.start();
}
}
I have a class variable, sum. Every time I start a new thread, I want the sum to increment. It seems that run is only being called once, and I can't find better info to tell me more about it. Is there a way I could accomplish this with locks? Here is some simple code:
public class MyClass implements Runnable{
static int sum = 0;
public static void main(String[] args) throws InterruptedException {
for(int i = 0; i < 5; ++i){
Thread t = new Thread(new MyClass());
t.start();
t = null;
}
}
#Override
public synchronized void run() {
++sum;
System.out.println(sum);
}
}
Keeping mutable state in static variables is a bad practice, but this is how you would fix this to work:
public class MyClass implements Runnable {
static AtomicInteger counter = new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 5; ++i) {
Thread t = new Thread(new MyClass());
t.start();
t = null;
}
}
#Override
public void run() {
int sum = counter.incrementAndGet();
System.out.println(sum);
}
}
Since sum is instance variable, for instance of MyClass there is a variable sum with initial value as 0. Mark the Sum as static to use it at class level.
public class MyClass implements Runnable{
static int sum = 0;
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 5; ++i) {
Thread t = new Thread(new MyClass());
t.start();
t = null;
}
}
public void run() {
synchronized (this) {
sum++;
System.out.println(sum);
}
}
}
This is the output:
1
2
3
4
5
I have a following code as below:
class Example {
private volatile int testValue = 0;
public int getTestValue() {
return testValue;
}
public void setTestValue(int testValue) {
this.testValue = testValue;
}
public void increment() {
this.testValue += 1;
}
}
class PrintThread extends Thread {
private Example example;
private int x = 0;
public PrintThread(Example example) {
this.example = example;
x = example.getTestValue();
}
public void run() {
while(true) {
if(x != example.getTestValue()) { // block 1
System.out.println("printThread: " + example.getTestValue());
x = example.getTestValue();
}
}
}
}
class IncrementorThread extends Thread {
private Example example;
public IncrementorThread(Example example) {
this.example = example;
}
public void run() {
while(true) {
example.increment();
System.out.println("incrementorThread: " + example.getTestValue());
try {
Thread.sleep(800);
} catch(Exception ex) {
}
}
}
}
public class VolatileExample {
public static void main(String args[]) {
Example ex = new Example();
new IncrementorThread(ex).start();
new PrintThread(ex).start();
}
}
When I remove volatile keyword in Example class then I never see the output of PrintThread. In PrintThread when I print out the testValue of example, value of example object still updated but the code in 'block 1' never be executed. Both thread still access the same object, can anyone explain me more detail about this? About the volatile keyword affected in this case
You should use atomic integers insteed of volatile fields. To get the idea why that is important try running code below. Here you have 3 types of variables, normal int, volatile int and AtomicInteger. Only AtomicInteger assure the thread safety of value. After running this simple code, you will see why.
public class Test {
private int threadCount = 10;
private int nonVolatileCount = 0;
private volatile int volatileCount = 0;
private AtomicInteger atomicCount = new AtomicInteger(0);
private CountDownLatch startLatch = new CountDownLatch(threadCount);
private CountDownLatch endLatch = new CountDownLatch(threadCount);
private class Task implements Runnable {
public void run() {
startLatch.countDown();
try {
startLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 1000000; i++) {
nonVolatileCount++;
volatileCount++;
atomicCount.incrementAndGet();
}
endLatch.countDown();
};
}
public static void main(String[] args) throws InterruptedException {
new Test().go();
}
public void go() throws InterruptedException {
for (int i = 0; i < threadCount; i++) {
new Thread(new Task()).start();
}
endLatch.await();
System.out.println("non volatile counter: " + nonVolatileCount);
System.out.println(" volatile counter: " + volatileCount);
System.out.println(" atomic counter: " + atomicCount.get());
}
}
Java Thread - i want to generate numbers in sequence eg: 1,2,3,4... (there will be 2 threads only ) 1st thread o/p will be 1 ,second thread o/p will be 2 , again 1st thread o/p will be 3 and so on , it can be upto 10 or upto n number whatever just wanna get the logic please help me guys :|
below is my attempt to do it but its not working i know there would be wait() and notify() methods for sure but cant figure out the proper way to use them !
class NumberGenerator
{
static int number = 0;
synchronized public int numGenerator()
{
for(int i=0;i<20;i++)
{
System.out.println(i);
number=i;
}
return number;
}
}
class FirstThreadClass extends Thread
{
NumberGenerator num;
FirstThreadClass(NumberGenerator num)
{
this.num = num;
}
public void run()
{
System.out.println("i am from 1st thread :"+num.numGenerator());
}
}
class SecondThreadClass extends Thread
{
NumberGenerator num;
SecondThreadClass(NumberGenerator num)
{
this.num = num;
}
public void run()
{
System.out.println("i am from 2nd thread :"+num.numGenerator());
}
}
public class ThreadTesting {
public static void main(String[] args) {
FirstThreadClass ftc = new FirstThreadClass(new NumberGenerator());
SecondThreadClass stc = new SecondThreadClass(new NumberGenerator());
ftc.start();
stc.start();
}
}
class NumberGenerator
{
static int counter = 0;
public synchronized int getNextNumber()
{
return counter++;
}
}
class FirstThreadClass
extends Thread
{
NumberGenerator num;
FirstThreadClass(NumberGenerator num)
{
this.num = num;
}
public void run()
{
System.out.println("i am from 1st thread :" + num.getNextNumber());
}
}
class SecondThreadClass
extends Thread
{
NumberGenerator num;
SecondThreadClass(NumberGenerator num)
{
this.num = num;
}
public void run()
{
System.out.println("i am from 2nd thread :" + num.getNextNumber());
}
}
public class ThreadTesting
{
public static void main(String[] args)
{
FirstThreadClass ftc = new FirstThreadClass(new NumberGenerator());
SecondThreadClass stc = new SecondThreadClass(new NumberGenerator());
for (int k = 0; k < 10; k++)
{
ftc.run();
stc.run();
}
}
}
You can have each thread generate numbers as follows:
Thread 1: 1, 3, 5, 7, 9, ...
Thread 2: 2, 4, 6, 8, 10, ...
add to a concurrent collection and sort afterwards.
Do they have to generate only one each time, or is it ok if thread1 generate 2 numbers, then thread 2 generates 1 number etc... ?
Use a static int field that will act as a counter, and access it in a synchronized way.
static int counter = 0;
public synchronized int getNextNumber(){
return counter++;
}
Then the threads do :
while(...whatever..){
System.out.print(getNextNumber());
}
you can achieve this using cyclic barrier, create a barrier and once two threads have generated one number each print the two numbers
class ThreadTest {
private CyclicBarrier cyclicBarrier = new CyclicBarrier(2, new Runnable() {
#Override
public void run() {
System.out.println(oddNumberGenerator.result);
System.out.println(evenNumberGenerator.result);
}
});
private NumberGenerator oddNumberGenerator = new NumberGenerator(1,11,2);
private NumberGenerator evenNumberGenerator = new NumberGenerator(2,10,2);
public void generateSeries(){
oddNumberGenerator.generateNumbers();
evenNumberGenerator.generateNumbers();
}
class NumberGenerator {
private Thread thread;
private int result;
private NumberGenerator(final int initialValue, final int maxValue,
final int stepSize) {
this.thread = new Thread(new Runnable() {
#Override
public void run() {
for (int i = initialValue; i <= maxValue; i = i + stepSize) {
try {
result = i;
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
});
}
public void generateNumbers() {
thread.start();
}
}
main(String[] args){
new ThreadTest().generateSeries();
}
}
You can achieve using wait and notifyAll() . But it is always better to use standard java concurrent classes to achieve it
public class PrintAlternateValues {
public static void main(String[] args) {
final NumberValue number = new NumberValue();
final Object lockObject = new Object();
new Thread(){
private NumberValue n = number;
#Override
public void run() {
synchronized (lockObject) {
while(n.getValue() < n.getEndPoint()){
while(n.isToggle()){
try{
lockObject.wait();
}catch(Exception e){
e.printStackTrace();
}
}
n.incrementValue();
System.out.println(getName() + " printing "+n.getValue());
n.setToggle(true);
lockObject.notifyAll();
}
}
}
}.start();
new Thread(){
private NumberValue n = number;
#Override
public void run() {
synchronized (lockObject) {
while(n.getValue() < n.getEndPoint()){
while(!n.isToggle()){
try{
lockObject.wait();
}catch(Exception e){
e.printStackTrace();
}
}
n.incrementValue();
System.out.println(getName() + " printing "+n.getValue());
n.setToggle(false);
lockObject.notifyAll();
}
}
}
}.start();
}
}
class NumberValue {
private int value;
private boolean toggle = true;
private int endPoint = 10;
public int getEndPoint() {
return endPoint;
}
public void setEndPoint(int endPoint) {
this.endPoint = endPoint;
}
public boolean isToggle() {
return toggle;
}
public void setToggle(boolean toggle) {
this.toggle = toggle;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public synchronized void incrementValue(){
this.value++;
}
}