How can I implement a thread that gets user input? - java

I've implemented a thread that get user input by keyboard. However, when user sets input my program returns an IllegalThreadStateException error, at line 23.
import java.util.Scanner;
public class Main {
static MyThread myThread = new MyThread();
static public boolean answered = false;
public static void main(String[] args) {
String s = "";
while (!s.equalsIgnoreCase("q")) {
int seconds = 0, average = 5;
if (seconds > average) {
myThread.stop();
String phrase = choosePhrase(seconds, average);
System.out.println(phrase);
Scanner keyboard = new Scanner(System.in);
s = keyboard.nextLine();
} else {
long createdMillis = System.currentTimeMillis();
myThread.start();
while (!answered && seconds < average) {
long nowMillis = System.currentTimeMillis();
seconds = (int) ((nowMillis - createdMillis) / 1000);
}
}
}
}
private static String choosePhrase(int seconds, int average) {
if (seconds > average + 10) {
return "¿D?";
} else if (seconds > average + 5) {
return "¿E?";
} else {
return "¿F?";
}
}
}
class MyThread extends Thread {
static String[] questions = {"¿A?", "¿B?", "¿C?"};
public void run() {
System.out.println("MyThread running");
Double d = Math.random() * 100;
int n = (int) (Math.ceil(d) % 3);
String question = questions[n];
System.out.println(question);
Scanner keyboard = new Scanner(System.in);
String s = keyboard.nextLine();
stop();
}
}
Why am I getting this exception? How do I make the thread gets and exits correctly to main function?

To make a thread exits proprely you have to use myThread.interrupt();

I've solved the issue with your suggestions:
import javax.swing.JOptionPane;
public class Main {
public static void main(String[] args) {
Latency latency = new Latency();
latency.start();
}
}
class Latency {
int seconds = 0, average = 5;
MyThread myThread;
ObjectToPass o = new ObjectToPass();
public void start() {
String s = "";
Thread t = null;
while (!s.equalsIgnoreCase("q")) {
// The program has just begun, or user has answered a question,
// or term has expired.
seconds = 0;
if (myThread != null) {
myThread.shutdown();
myThread = null;
}
if (o.answered) {
o.answered = false;
myThread = new MyThread(o, new String[]{"¿A?", "¿B?", "¿C?"});
} else {
myThread = new MyThread(o, new String[]{"¿D?", "¿E?", "¿F?"});
}
t = new Thread(myThread);
t.start();
long createdMillis = System.currentTimeMillis();
while (!this.o.getPlay() && seconds < average) {
long nowMillis = System.currentTimeMillis();
seconds = (int) ((nowMillis - createdMillis) / 1000);
}
}
}
}
class ObjectToPass {
boolean answered = true;
public synchronized boolean getPlay() {
return answered;
}
public synchronized void setPlay(boolean answered) {
this.answered = answered;
}
}
class MyThread implements Runnable {
ObjectToPass o;
static String[] questions;
public MyThread(ObjectToPass o, String[] questions) {
this.o = o;
this.questions = questions;
}
public void run() {
// System.out.println("MyThread running");
Double d = Math.random() * 100;
int n = (int) (Math.ceil(d) % 3);
String question = questions[n];
System.out.println(question);
// Scanner keyboard = new Scanner(System.in);
// String s = keyboard.nextLine();
Object[] options = {"Yes", "No"};
int oo = JOptionPane.showOptionDialog(null,
question, "Question", JOptionPane.YES_OPTION,
JOptionPane.NO_OPTION, null, options, options[0]);
this.o.setPlay(true);
}
public void shutdown() {
Thread.currentThread().interrupt();
return;
}
}

Related

Multithreading actively waiting

I'm working on a problem where I have to use 4 different threads to write out a LETTER event INTERNAL ms AMOUNT times. The first 3 threads start right away the forth one is awaiting for one of them to finish & then starting.
I have got the code to a point where is doing what it should although the code is not "ending" it's actively waiting.
Could you advise what could be the issue here?
public class PrinterThread extends Thread {
private String letter;
private int internal;
private int amount;
public PrinterThread(String letter, int internal, int amount){
this.letter = letter;
this.internal = internal;
this.amount = amount;
}
public void run(){
for (int i = 1; i <= amount; i++) {
System.out.println(letter);
try {
Thread.sleep(internal);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main {
public static void main(String[] args) {
PrinterThread printerThread = new PrinterThread("A", 1, 1000);
PrinterThread printerThread1 = new PrinterThread("B", 1, 1000);
PrinterThread printerThread2 = new PrinterThread("C", 1, 1);
PrinterThread printerThread3 = new PrinterThread("D", 5, 50);
printerThread.start();
printerThread1.start();
printerThread2.start();
while(!printerThread3.isAlive()){
if (!printerThread.isAlive() || !printerThread1.isAlive() || !printerThread2.isAlive()) {
printerThread3.start();
}
}
}
}
Break out of the while loop, once you have started printerThread3.
public class PrinterThread extends Thread {
private String letter;
private int internal;
private int amount;
public PrinterThread(String letter, int internal, int amount){
this.letter = letter;
this.internal = internal;
this.amount = amount;
}
public void run(){
for (int i = 1; i <= amount; i++) {
System.out.println(letter);
try {
Thread.sleep(internal);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main {
public static void main(String[] args) {
PrinterThread printerThread = new PrinterThread("A", 1, 1000);
PrinterThread printerThread1 = new PrinterThread("B", 1, 1000);
PrinterThread printerThread2 = new PrinterThread("C", 1, 1);
PrinterThread printerThread3 = new PrinterThread("D", 5, 50);
printerThread.start();
printerThread1.start();
printerThread2.start();
while(!printerThread3.isAlive()){
if (!printerThread.isAlive() || !printerThread1.isAlive() || !printerThread2.isAlive()) {
printerThread3.start();
break;
}
}
//If you want main to wait for all the others to complete, then add this...
printerThread.join();
printerThread1.join();
printerThread2.join();
printerThread3.join();
}
}

How can I distinguish a winner in this thread race?

I have been writing a race code for a class I am in that races two threads, a tortoise and a hare. I can get both of them to run for 80 units but I don't know how to write a code that determines and outputs who the winner is. Any help would be appreciated because I am super new to coding.
I have the tortoise, hare, and raceParticipant classes. My driver class looks like this, where I would assume I put the winner code?
package Domain;
public class Driver
{
public static void main(String[] args)
{
Hare bob = new Hare();
Tortoise fred = new Tortoise();
int winDistance = 80;
do {
bob.sprint();
fred.sprint();
bob.display();
fred.display();
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}while(bob.getTotalDistance() < winDistance && fred.getTotalDistance() < winDistance);
}
}
My sprint method is
public int sprint()
{
int sleep = generator.nextInt(100);
int sprintDistance = 0;
if (sleep > sleepPercent)
{
sprintDistance = generator.nextInt(topSpeed) + 1;
}
totalDistance +=sprintDistance;
return sprintDistance;
}
I don't see you creating a new thread anywhere.
You can create a Hare class like this:
public class Hare implements Runnable {
private static final int SLEEP_DURATION = 3000; //milliseconds
private static final int SPEED = 3; //units per second
private int distanceToRun;
private final RaceFinishListener listener;
public Hare(int distanceToRun, RaceFinishListener listener) {
this.distanceToRun = distanceToRun;
this.listener = listener;
}
#Override
public void run() {
do {
distanceToRun -= SPEED;
try {
Thread.sleep(SLEEP_DURATION);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (distanceToRun > 0);
listener.onRaceFinished(getClass().getSimpleName());
}
}
and a similar Tortoise class with these variables:
private static final int SLEEP_DURATION = 1000; //sleeps less
private static final int SPEED = 1; //but is slow
Then create a listener to get notified when someone has finished:
public interface RaceFinishListener {
void onRaceFinished(String finisher);
}
and finally your main class:
public class Test implements RaceFinishListener {
private String winner;
private static final int DISTANCE_TO_RUN = 10;
public static void main(String[] args) {
new Test().race();
}
private void race() {
Hare bob = new Hare(DISTANCE_TO_RUN, this);
Tortoise fred = new Tortoise(DISTANCE_TO_RUN, this);
new Thread(bob).start();
new Thread(fred).start();
}
#Override
public void onRaceFinished(String finisher) {
synchronized (this) {
if (winner == null) {
winner = finisher;
System.out.println(finisher + " is the winner!");
} else {
System.out.println(finisher + " lost.");
}
}
}
}
Output
Tortoise is the winner!
Hare lost.
After this line:
}while(bob.getTotalDistance() < winDistance && fred.getTotalDistance() < winDistance);
You would just have:
boolean bobWins = (bob.getTotalDistance() >= winDistance);
boolean fredWins = (fred.getTotalDistance() >= winDistance);
if (bobWins && fredWins) {
System.out.println("It's a tie");
}
else if (bobWins) {
System.out.println("Bob Wins");
}
else {
System.out.println("Fred Wins");
}

How to print fibonacci number, multithreading?

The task is to write a program that creates and starts two threads ThreadFibonacci and ThreadOutput. ThreadFiobnacci should calculate the fibonacci numbers and put the results in its static public variable. ThreadOutput should output the fibonacci number and ThreadOutput has to be a daemon thread. You have to make the thread write out each fibonacci number only once. I do not know how to do that last part of the task.
You can only use sleep, interrupt, volatile and join.
Here is what I tried:
import java.util.Scanner;
public class Zadatak2{
public static void main(String[] args){
Scanner reader = new Scanner(System.in);
System.out.println("Enter a number: ");
int n = reader.nextInt();
Thread threadFibonaci = new Thread(new ThreadFibonaci(n));
Thread threadOutput = new ThreadOutput();
threadFibonaci.start();
threadOutput.start();
}
}
class ThreadFibonaci implements Runnable{
public static volatile long fn;
private int n;
public ThreadFibonaci(int n){
this.n = n;
}
public void run(){
long f0 = 0;
fn = f0;
try{
Thread.sleep(500);
}catch(Exception e){
e.printStackTrace();
}
long f1 = 1;
fn = f1;
try{
Thread.sleep(500);
}catch(Exception e){
e.printStackTrace();
}
for(int i=0; i<n; i++){
fn = f0 + f1;
f0 = f1;
f1 = fn;
try{
Thread.sleep(500);
}catch(Exception e){
e.printStackTrace();
}
}
}
}
class ThreadOutput extends Thread{
public ThreadOutput(){
setDaemon(true);
}
public void run(){
while(true){
System.out.println(ThreadFibonaci.fn);
try{
Thread.sleep(500);
}catch(Exception e){
e.printStackTrace();
}
}
}
}
You need top use one more volatile variable to store a flag whether current number was already printed or not
class ThreadFibonaci implements Runnable{
public static volatile long fn;
public static volatile boolean printed = false;
private int n;
public ThreadFibonaci(int n){
this.n = n;
}
public void run(){
long f0 = 0;
fn = f0;
while (!printed) {
try{
Thread.sleep(500);
}catch(Exception e){
e.printStackTrace();
}
}
long f1 = 1;
fn = f1;
printed = false;
while (!printed) {
try{
Thread.sleep(500);
}catch(Exception e){
e.printStackTrace();
}
}
for(int i=0; i<n; i++){
fn = f0 + f1;
f0 = f1;
f1 = fn;
printed = false;
while (!printed) {
try{
Thread.sleep(500);
}catch(Exception e){
e.printStackTrace();
}
}
}
}
}
class ThreadOutput extends Thread{
public ThreadOutput(){
setDaemon(true);
}
public void run(){
while(true){
while (ThreadFibonaci.printed) {
try{
Thread.sleep(500);
}catch(Exception e){
e.printStackTrace();
}
}
System.out.println(ThreadFibonaci.fn);
ThreadFibonaci.printed = true;
}
}
}
This uses a single volatile field to hold the value. when the value is 0 a new value can be published and when the value is negative, it acts as a poison pill, stopping the printing thread.
class A {
static volatile long value = 0;
static void publish(long x) {
while (value > 0) ;
value = x;
}
static long next() {
while (value == 0) ;
long ret = value;
if (ret > 0) value = 0;
return ret;
}
public static void main(String[] args) {
System.out.println("Enter a number: ");
int n = new java.util.Scanner(System.in).nextInt();
new Thread(() -> {
long a = 1; publish(a);
long b = 1; publish(b);
for (int i = 2; i < n; i++) {
long c = a + b; publish(c);
a = b; b = c;
}
publish(-1); // poison pill
}).start();
new Thread(() -> {
for (; ; ) {
long value = next();
if (value < 0) break;
System.out.println(value);
}
}).start();
}
}

3 Threads Printing numbers in sequence

I am trying to write a simple code to print numbers in sequence. Scenario is like
Thread Number
T1 1
T2 2
T3 3
T1 4
T2 5
T3 6
T1 7
T2 8
T3 9
...and so on.
Here is the
public class ThreadNumberPrinter {
Object monitor = new Object();
AtomicInteger number = new AtomicInteger(1);
public static void main(String[] args) {
ThreadNumberPrinter tnp = new ThreadNumberPrinter();
Thread t1 = new Thread(tnp.new Printer(1, 3));
Thread t2 = new Thread(tnp.new Printer(2, 3));
Thread t3 = new Thread(tnp.new Printer(3, 3));
t3.start();
t1.start();
t2.start();
}
class Printer implements Runnable {
int threadId;
int numOfThreads;
public Printer(int id, int nubOfThreads) {
threadId = id;
this.numOfThreads = nubOfThreads;
}
public void run() {
print();
}
private void print() {
try {
while (true) {
Thread.sleep(1000l);
synchronized (monitor) {
if (number.get() % numOfThreads != threadId) {
monitor.wait();
} else {
System.out.println("ThreadId [" + threadId
+ "] printing -->"
+ number.getAndIncrement());
monitor.notifyAll();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
But just after 2nd thread runs and prints the number 2, all thread get into wait stage and nothing gets printed. I am not sure where I am doing wrong.
Any help would be greatly appreciated.
public class TestClass {
private volatile Integer count = 1;
private volatile Integer threadIdToRun = 1;
private Object object = new Object();
public static void main(String[] args) {
TestClass testClass = new TestClass();
Thread t1 = new Thread(testClass.new Printer(1));
Thread t2 = new Thread(testClass.new Printer(2));
Thread t3 = new Thread(testClass.new Printer(3));
t1.start();
t2.start();
t3.start();
}
class Printer implements Runnable {
private int threadId;
public Printer(int threadId) {
super();
this.threadId = threadId;
}
#Override
public void run() {
try {
while (count <= 20) {
synchronized (object) {
if (threadId != threadIdToRun) {
object.wait();
} else {
System.out.println("Thread " + threadId + " printed " + count);
count += 1;
if (threadId == 1)
threadIdToRun = 2;
else if (threadId == 2)
threadIdToRun = 3;
else if (threadId == 3)
threadIdToRun = 1;
object.notifyAll();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Above program gives output
Thread 1 printed 1
Thread 2 printed 2
Thread 3 printed 3
Thread 1 printed 4
Thread 2 printed 5
Thread 3 printed 6
Thread 1 printed 7
Thread 2 printed 8
Thread 3 printed 9
Thread 1 printed 10
Thread 2 printed 11
Thread 3 printed 12
Thread 1 printed 13
Thread 2 printed 14
Thread 3 printed 15
Thread 1 printed 16
Thread 2 printed 17
Thread 3 printed 18
Thread 1 printed 19
Thread 2 printed 20
Well, the problem is that modulo 3 % 3 is 0. Change your threadIds to 0..2 instead of 1..3 and hopefully it should work.
Though this is a bad way for using threads, if we still want it a generic solution can be to have a worker thread which will store its id:
class Worker extends Thread {
private final ResourceLock resourceLock;
private final int threadNumber;
private final AtomicInteger counter;
private volatile boolean running = true;
public Worker(ResourceLock resourceLock, int threadNumber, AtomicInteger counter) {
this.resourceLock = resourceLock;
this.threadNumber = threadNumber;
this.counter = counter;
}
#Override
public void run() {
while (running) {
try {
synchronized (resourceLock) {
while (resourceLock.flag != threadNumber) {
resourceLock.wait();
}
System.out.println("Thread:" + threadNumber + " value: " + counter.incrementAndGet());
Thread.sleep(1000);
resourceLock.flag = (threadNumber + 1) % resourceLock.threadsCount;
resourceLock.notifyAll();
}
} catch (Exception e) {
System.out.println("Exception: " + e);
}
}
}
public void shutdown() {
running = false;
}
}
The ResourceLock class would store flag and max threads count:
class ResourceLock {
public volatile int flag;
public final int threadsCount;
public ResourceLock(int threadsCount) {
this.flag = 0;
this.threadsCount = threadsCount;
}
}
And then main class can use it as below:
public static void main(String[] args) throws InterruptedException {
final int threadsCount = 3;
final ResourceLock lock = new ResourceLock(threadsCount);
Worker[] threads = new Worker[threadsCount];
final AtomicInteger counter = new AtomicInteger(0);
for(int i=0; i<threadsCount; i++) {
threads[i] = new Worker(lock, i, counter);
threads[i].start();
}
Thread.sleep(10000);
System.out.println("Will try to shutdown now...");
for(Worker worker: threads) {
worker.shutdown();
}
}
Here after a certain delay we may like to stop the count and the method shutdown in worker provides this provision.
Below code uses the logic of notifying the next thread to print the number and then incrementing it by 1 and then again notifying the next thread and then go in wait state till some thread notifies it.
Eg. T1 first prints the value and then makes boolean "second" true for T2 to print the next number. T2 after printing the number makes boolean "third" true for T3. T3 does the same thing by making boolean "first" true for T1 to print the next number.
T1 -> T2 -> T3 -> T1 -> T2 -> T3 -> ........ and so on.
public class Test{
public static volatile int i = 0;
public static void main(String[] args) throws InterruptedException {
Object monitor = new Object();
Notifier notifier = new Notifier(monitor);
Thread thread1 = new Thread(notifier, "T1");
Thread thread2 = new Thread(notifier, "T2");
Thread thread3 = new Thread(notifier, "T3");
thread1.start();
thread2.start();
thread3.start();
}
}
class Notifier implements Runnable {
private Object monitor = null;
private static int i = 1;
private static boolean first = true;
private static boolean second = false;
private static boolean third = false;
public Notifier(Object objcurr) {
this.monitor = objcurr;
}
#Override
public void run() {
try {
while (true) {
synchronized (monitor) {
String Tname = Thread.currentThread().getName();
if (first && Tname.equalsIgnoreCase("T1")) {
print();
first = false;
second = true;
monitor.notifyAll();
monitor.wait();
} else if (second && Tname.equalsIgnoreCase("T2")) {
print();
second = false;
third = true;
monitor.notifyAll();
monitor.wait();
} else if (third && Tname.equalsIgnoreCase("T3")) {
print();
third = false;
first = true;
monitor.notifyAll();
monitor.wait();
} else {
monitor.wait();
}
}
Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void print() {
System.out.println(Thread.currentThread().getName() + " - " + Notifier.i++);
}
How about this?
public class PrintNumbers implements Runnable {
public static final int NO_OF_THREADS = 3;
public static final int MAX_DIGIT = 20;
public static final String THREAD_NAME_PREFIX = "t";
volatile int current = 1;
private Object lock = new Object();
public static void main(String[] args) {
PrintNumbers printNumbers = new PrintNumbers();
for (int i = 1; i <= NO_OF_THREADS; i++) {
new Thread(printNumbers, THREAD_NAME_PREFIX + i).start();
}
}
#Override
public void run() {
String printThread;
while (current < MAX_DIGIT) {
synchronized (lock) {
if (current % NO_OF_THREADS != 0) {
printThread = THREAD_NAME_PREFIX + current % NO_OF_THREADS;
} else {
printThread = THREAD_NAME_PREFIX + NO_OF_THREADS;
}
if (!printThread.equals(Thread.currentThread().getName())) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (printThread.equals(Thread.currentThread().getName())) {
System.out.println(String.format("Thread %s : %s", Thread.currentThread().getName(), current));
current = current + 1;
}
lock.notifyAll();
}
}
}
}
package com.sourav.mock.Thread;
import java.util.concurrent.atomic.AtomicInteger;
public class ThreeThreadComunication implements Runnable {
AtomicInteger counter;
int[] array;
static final Object mutex = new Object();
public ThreeThreadComunication(int[] array, AtomicInteger counter){
this.counter = counter;
this.array = array;
}
#Override
public void run() {
int i = 0;
while(i < array.length){
synchronized(mutex){
if(Integer.parseInt(Thread.currentThread().getName()) == counter.get()){
System.out.println(array[i]);
if(counter.get() == 3){
counter.getAndSet(1);
}else{
int c = counter.get();
counter.getAndSet(++c);
}
i++;
}
mutex.notifyAll();
try {
mutex.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
package com.sourav.mock.Thread;
import java.util.concurrent.atomic.AtomicInteger;
public class ThreeThreadComunicationTest {
public static void main(String[] args) {
AtomicInteger counter = new AtomicInteger(1);
int[] array1 = new int[]{1, 4, 7};
int[] array2 = new int[]{2, 5, 8};
int[] array3 = new int[]{3, 6, 9};
ThreeThreadComunication obj1 = new ThreeThreadComunication(array1, counter);
ThreeThreadComunication obj2 = new ThreeThreadComunication(array2, counter);
ThreeThreadComunication obj3 = new ThreeThreadComunication(array3, counter);
Thread t1 = new Thread(obj1, "1");
Thread t2 = new Thread(obj2, "2");
Thread t3 = new Thread(obj3, "3");
t1.start();
t2.start();
t3.start();
}
}
public class EvenOdd1 {
//public static String str ="str1";
public static void main(String[] args) {
// TODO Auto-generated method stub
EvenOdd1 edd1 = new EvenOdd1();
AbThread tr2 = new AbThread(0,edd1);
AbThread tr3 = new AbThread(1,edd1);
AbThread tr4 = new AbThread(2,edd1);
tr2.start();
tr3.start();
tr4.start();
}
}
class AbThread extends Thread {
int mod;
int mod_count=1;
EvenOdd1 edd1;
public static int count=1;
int num_thread=3;
public AbThread(int mod,EvenOdd1 edd1){
this.mod = mod;
this.edd1 = edd1;
}
public void run()
{
synchronized(edd1)
{
try{
while(true){
while(count%num_thread!=mod)
edd1.wait();
if(count==30)
break;
print();
edd1.wait();
}
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void print()
{
int val = mod==1?2*mod_count:(mod==2?3*mod_count:4*mod_count);
System.out.println(Thread.currentThread().getName() + " : " + val);
edd1.notifyAll();
count=count+1;
this.mod_count++ ;
}
}
public class PrintThreadsSequentially {
static int number = 1;
static final int PRINT_NUMBERS_UPTO = 20;
static Object lock = new Object();
static class SequentialThread extends Thread {
int remainder = 0;
int noOfThreads = 0;
public SequentialThread(String name, int remainder, int noOfThreads) {
super(name);
this.remainder = remainder;
this.noOfThreads = noOfThreads;
}
#Override
public void run() {
while (number < PRINT_NUMBERS_UPTO) {
synchronized (lock) {
while (number % noOfThreads != remainder) { // wait for numbers other than remainder
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(getName() + " value " + number);
number++;
lock.notifyAll();
}
}
}
}
public static void main(String[] args) {
SequentialThread first = new SequentialThread("First Thread", 0, 4);
SequentialThread second = new SequentialThread("Second Thread", 1, 4);
SequentialThread third = new SequentialThread("Third Thread", 2, 4);
SequentialThread fourth = new SequentialThread("Fourth Thread", 3, 4);
first.start(); second.start(); third.start(); fourth.start();
}
}
The ThreadSynchronization class can be used to print numbers between 'n' no. of threads in sequence.
The logic is to create a common object between each of the consecutive threads and use 'wait', 'notify' to print the numbers in sequence.
Note: Last thread will share an object with the first thread.
You can change the 'maxThreads' value to increase or decrease the number of thread in the program before running it.
import java.util.ArrayList;
import java.util.List;
public class ThreadSynchronization {
public static int i = 1;
public static final int maxThreads = 10;
public static void main(String[] args) {
List<Object> list = new ArrayList<>();
for (int i = 0; i < maxThreads; i++) {
list.add(new Object());
}
Object currObject = list.get(maxThreads - 1);
for (int i = 0; i < maxThreads; i++) {
Object nextObject = list.get(i);
RunnableClass1 a = new RunnableClass1(currObject, nextObject, i == 0 ? true : false);
Thread th = new Thread(a);
th.setName("Thread - " + (i + 1));
th.start();
currObject = list.get(i);
}
}
}
class RunnableClass implements Runnable {
private Object currObject;
private Object nextObject;
private boolean firstThread;
public RunnableClass(Object currObject, Object nextObject, boolean first) {
this.currObject = currObject;
this.nextObject = nextObject;
this.firstThread = first;
}
#Override
public void run() {
int i = 0;
try {
if (firstThread) {
Thread.sleep(5000);
firstThread = false;
System.out.println(Thread.currentThread().getName() + " - " + ThreadSynchronization.i++);
synchronized (nextObject) {
nextObject.notify();
}
}
while (i++ < Integer.MAX_VALUE) {
synchronized (currObject) {
currObject.wait();
}
System.out.println(Thread.currentThread().getName() + " - " + ThreadSynchronization.i++);
Thread.sleep(1000);
synchronized (nextObject) {
nextObject.notify();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
I have tried it below simple way to print in sequence using three threads and it is working well.
public class AppPrint123 {
static int count = 1;
static int counter = 1;
static Object lock = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
public void run() {
while (true) {
synchronized (lock) {
try {
Thread.sleep(100);
while (count != 1) {
lock.wait();
}
System.out.println(Thread.currentThread().getName() + ": " + counter);
count++;
counter++;
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.notifyAll();
}
}
}
}, "T1");
Thread t2 = new Thread(new Runnable() {
public void run() {
while (true) {
synchronized (lock) {
try {
Thread.sleep(100);
while (count != 2) {
lock.wait();
}
System.out.println(Thread.currentThread().getName() + ": " + counter);
counter++;
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.notifyAll();
}
}
}
}, "T2");
Thread t3 = new Thread(new Runnable() {
public void run() {
while (true) {
synchronized (lock) {
try {
Thread.sleep(100);
while (count != 3) {
lock.wait();
}
System.out.println(Thread.currentThread().getName() + ": " + counter);
count = count - 2;
counter++;
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.notifyAll();
}
}
}
}, "T3");
t1.start();
t2.start();
t3.start();
}
}
You can print count variable instead if you want to generate output like 123123123 in sequence using three threads.
Bad way to do but ask is to implement using multiple threads:
private static AtomicInteger currentThreadNo = new AtomicInteger(0);
private static int currentNo = 1;
private static final Object lock = new Object();
Above, these values are static so that they remain same for all the worker objects.
import java.util.concurrent.atomic.AtomicInteger;
public class PrintNumbersUsingNThreads implements Runnable {
private final int threadNo;
private final int totalThreads;
private static AtomicInteger currentThreadNo = new AtomicInteger(0);
private static int currentNo = 1;
private static final Object lock = new Object();
public PrintNumbersUsingNThreads(int threadNo, int totalThreads) {
this.threadNo = threadNo;
this.totalThreads = totalThreads;
}
#Override
public void run() {
while (true) {
while (currentThreadNo.get() % totalThreads != threadNo) {
try {
synchronized (lock) {
lock.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " printing " + currentNo);
currentNo++;
int curr = currentThreadNo.get();
if (curr == totalThreads) {
currentThreadNo.set(1);
} else {
currentThreadNo.incrementAndGet();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock) {
lock.notifyAll();
}
}
}
public static void main(String[] args) {
int totalThreads = 3;
for(int i = 0; i < totalThreads; i++){
new Thread(new PrintNumbersUsingNThreads(i,totalThreads),"thread"+i).start();
}
}
}
output:
thread0 printing 1
thread1 printing 2
thread2 printing 3
thread0 printing 4
thread1 printing 5
thread2 printing 6
thread0 printing 7
thread1 printing 8
thread2 printing 9
thread0 printing 10
thread1 printing 11
thread2 printing 12
thread0 printing 13
thread1 printing 14
thread2 printing 15
thread0 printing 16
thread1 printing 17
thread2 printing 18
Below is very generic code. i agree it is not good practice to use multiple threads for such cases
class MultipleThreads implements Runnable {
AtomicInteger integer;
int max_val = 100;
int remainder;
int numofThreads;
public MultipleThreads(AtomicInteger integer, int remainder, int numofThreads) {
this.integer = integer;
this.remainder = remainder;
this.numofThreads = numofThreads;
}
#Override
public void run() {
while (integer.intValue() <= max_val) {
synchronized (integer) {
while (integer.intValue() % numofThreads != remainder) {
try {
integer.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (integer.intValue() > max_val)
break;
System.out.println("printing :" + Thread.currentThread().getName() + " : " + integer.getAndIncrement());
integer.notifyAll();
}
}
}
}
public class ThreadSynchronization {
public static void main(String[] args) {
AtomicInteger at = new AtomicInteger(1);
MultipleThreads th1 = new MultipleThreads(at, 1, 5);
MultipleThreads th2 = new MultipleThreads(at, 2, 5);
MultipleThreads th3 = new MultipleThreads(at, 3, 5);
MultipleThreads th4 = new MultipleThreads(at, 4, 5);
MultipleThreads th5 = new MultipleThreads(at, 0, 5);
new Thread(th1).start();
new Thread(th2).start();
new Thread(th3).start();
new Thread(th4).start();
new Thread(th5).start();
}
}
Also, make sure to use pthread_cond_broadcast instead of phread_cond_signal
#include "stdio.h"
#include "stdlib.h"
#include "pthread.h"
pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t condition_var = PTHREAD_COND_INITIALIZER;
void *functionCount1();
void *functionCount2();
void *functionCount3();
int count = 0;
#define COUNT_DONE 10
void main()
{
pthread_t thread1, thread2, thread3;
pthread_create( &thread1, NULL, &functionCount1, NULL);
pthread_create( &thread2, NULL, &functionCount2, NULL);
pthread_create( &thread3, NULL, &functionCount3, NULL);
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
pthread_join( thread3, NULL);
exit(0);
}
// Let me write what I think
// we can;t do he %2 %3 since multiple threads may satisfy the conditions.
// count = 0; count % 3 = 0
// count = 1; count % 3 = 1
// count = 2; count % 3 = 2
// count = 3; cooun % 3 = 0
// Print odd numbers
void *functionCount1()
{
for(;;) {
// Lock mutex and then wait for signal to relase mutex
pthread_mutex_lock( &count_mutex );
if ( count % 3 == 0 ) {
printf("Counter value functionCount1: %d\n",count);
count++;
pthread_cond_broadcast( &condition_var );
} else {
pthread_cond_wait( &condition_var, &count_mutex );
}
if ( count >= COUNT_DONE ) {
pthread_mutex_unlock( &count_mutex );
return(NULL);
}
pthread_mutex_unlock( &count_mutex );
}
}
// print even numbers
void *functionCount2()
{
for(;;) {
// Lock mutex and then wait for signal to relase mutex
pthread_mutex_lock( &count_mutex );
if ( count % 3 == 1 ) {
printf("Counter value functionCount2: %d\n",count);
count++;
pthread_cond_broadcast( &condition_var );
} else {
pthread_cond_wait( &condition_var, &count_mutex );
}
if( count >= COUNT_DONE ) {
pthread_mutex_unlock( &count_mutex );
return(NULL);
}
pthread_mutex_unlock( &count_mutex );
}
}
// print even numbers
void *functionCount3()
{
for(;;) {
// Lock mutex and then wait for signal to relase mutex
pthread_mutex_lock( &count_mutex );
if ( count % 3 == 2 ) {
printf("Counter value functionCount3: %d\n",count);
count++;
pthread_cond_broadcast( &condition_var );
} else {
pthread_cond_wait( &condition_var, &count_mutex );
}
if( count >= COUNT_DONE ) {
pthread_mutex_unlock( &count_mutex );
return(NULL);
}
pthread_mutex_unlock( &count_mutex );
}
}
Here is my solution. It is pretty simple and easy to understand. It will help if you are using static variables...
Note that using a lock object is crucial as I tried initially with the this keyword(ex: synchronized(this) ), but it was not been synchronized among all threads.
public class Assignment_Three_Threads {
public static int TotalNumberOfThreads = 3;
public static void main(String[] args) {
multiThread t1 = new multiThread(1);
multiThread t2 = new multiThread(2);
multiThread t3 = new multiThread(3);
t1.start();
t2.start();
t3.start();
}
}
class multiThread extends Thread{
int k=2;
private int threadId ;
private static int threadIdToRun = 1;
private static final Object lock = new Object();
multiThread(int id)
{
super();
this.threadId = id;
}
#Override
public void run() {
for (int i = 0; i < k; i++) {
synchronized (lock) {
while(true) {
if (this.threadId != threadIdToRun) {
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
if (this.threadId == threadIdToRun) {
System.out.println("Thread : " + this.threadId);
threadIdToRun =
(threadIdToRun % Assignment_Three_Threads.TotalNumberOfThreads) + 1;
// System.out.println("Next Thread to be printed " + threadIdToRun);
lock.notifyAll();
break;
}
}
}
}
}
}
A general solution for any number of Threads-
for 3 thread logic =MIN % 3 != reminder
for 4 thread= MIN % 4 != reminder
public class PrintSequenceRunnable1 implements Runnable {
int reminder;
static Object lock=new Object();
static int MIN=1;
int MAX=20;
PrintSequenceRunnable1(int reminder){
this.reminder=reminder;
}
public static void main(String[] args) {
Thread t1= new Thread(new PrintSequenceRunnable1(1),"T1");
Thread t2= new Thread(new PrintSequenceRunnable1(2),"T2");
Thread t3= new Thread(new PrintSequenceRunnable1(0),"T3");
t1.start();
t2.start();
t3.start();
}
#Override
public void run() {
synchronized (lock) {
while (MIN < MAX - 1) {
while (MIN % 3 != reminder) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "-" + MIN);
MIN++;
lock.notifyAll();
}
}
}
}
public class ThreadTask implements Runnable {
private int counter;
private int threadID;
private final Object lock;
private int prev;
public ThreadTask(Object obj, int threadid, int counter){
this.lock = obj; // monitor
this.threadID = threadid; //id of thread
this.counter = counter;
this.prev =threadid + 1;
}
public void run(){
while(counter<100){
synchronized(lock){
if(counter == this.prev && this.threadID % 3 == this.threadID){
System.out.println("T" + this.threadID + " = " + this.prev);
this.prev = this.prev + 3;
}
counter++;
lock.notifyAll();
try{
lock.wait();
}catch(Exception e){
e.printStackTrace();
}
}
}
}
}
public class ThreadMain {
static volatile int counter = 1;
public static void main(String args[]) throws InterruptedException{
final Object lock = new Object();
ThreadTask first = new ThreadTask(lock, 0, counter);
ThreadTask second = new ThreadTask(lock, 1, counter);
ThreadTask third = new ThreadTask(lock, 2, counter);
Thread t1 = new Thread(first, "first");
Thread t2 = new Thread(second, "second");
Thread t3 = new Thread(third, "third");
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
}
}
package ThreadCoreConcepts;
import java.util.ArrayList;
import java.util.List;
/**
* 3 Thread T1,T2,T3 will print output {1,2,3 4,5,6 7,8,9} Where T1 will print
* {1,4,7} , T2 will print { 2,5,8} and T3 will print {3,6,9}
*
* #author harsmahe
*
*/
public class ThreeThreadSequenceGen {
private volatile static int value = 1;
public static void main(String args[]) throws InterruptedException {
ThreeThreadSequenceGen gen = new ThreeThreadSequenceGen();
Object mutex = new Object();
Thread t1 = new Thread(gen.new RunThread(1, mutex));
t1.setName("1");
Thread t2 = new Thread(gen.new RunThread(2, mutex));
t2.setName("2");
Thread t3 = new Thread(gen.new RunThread(3, mutex));
t3.setName("3");
t1.start();
t2.start();
t3.start();
}
class RunThread implements Runnable {
private int start = 0;
private Object mutex;
private List<Integer> list = new ArrayList<Integer>();
public RunThread(final int start, Object mutex) {
// TODO Auto-generated constructor stub
this.start = start;
this.mutex = mutex;
}
#Override
public void run() {
try {
while (value <= 9) {
// while (true) {
// TODO Auto-generated method stub
int name = Integer.valueOf(Thread.currentThread().getName());
// System.out.println("[" + Thread.currentThread().getName()
// + "]");
// notifyAll();
synchronized (mutex) {
if (name == 1 && value == start) {
list.add(value);
System.out.println("[" + Thread.currentThread().getName() + "]" + value);
start = start + 3;
value++;
mutex.notifyAll();
mutex.wait();
} else if (name == 2 && value == start) {
System.out.println("[" + Thread.currentThread().getName() + "]" + value);
list.add(value);
start = start + 3;
value++;
mutex.notifyAll();
mutex.wait();
} else if (name == 3 && value == start) {
System.out.println("[" + Thread.currentThread().getName() + "]" + value);
list.add(value);
start = start + 3;
value++;
mutex.notifyAll();
if (value < 9) {
mutex.wait();
}
} else {
mutex.notifyAll();
// mutex.wait();
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// System.out.println(list);
}
}
}
}

Scheduling Two Separate Timers in Java and changing Period of one timer

I have two Timers in java that are scheduled independently. Both timers have different Task.
Timer 1 increments a number and Timer 2 changes the period of Timer 1. Here is the code where I am using two timers
public class Receiver
{
public static int totalBufferCapacity = 1024;
public static int totalPacketsDropped = 0;
public static int totalPacketsServiced = 0;
public static int totalPacketsReceived = 0;
public static int timesBufferGetsFull = 0;
public static int timesIntervelChanged = 0;
public static Socket clientSocket;
public static BufferedReader br;
public static ArrayList<String> buffer;
public static String START = "Start";
public static String STOP = "Stop";
public static String token = "1";
public static boolean flag;
public static Timer timer;
public static int Max = 80;
public static int Min = 40;
public static int rand;
public static PrintStream ps;
public static String packet;
public static Timer timer_2;
public static consumeArrayItems task;
public static void main(String[] args)
{
flag = true;
try
{
init(args[0], args[1]);
while (flag)
{
storePacketInArray();
}
} catch (Exception e)
{
e.printStackTrace();
}
}
public static void init(String localHost, String portNumber)
{
try
{
// inet address which is local host in this case
InetAddress acceptorHost = InetAddress.getByName(localHost);
// port number at which the sender wants to communicate
int serverPortNum = Integer.parseInt(portNumber);
clientSocket = new Socket(acceptorHost, serverPortNum);
} catch (IOException e)
{
e.printStackTrace();
}
}
public static void storePacketInArray()
{
try
{
if (br == null)
{
br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
}
packet = new String(br.readLine());
if (packet.compareToIgnoreCase("Start") == 0)
{
token = START;
buffer = new ArrayList<String>(totalBufferCapacity);
} else if (packet.compareToIgnoreCase("Stop") == 0)
{
stopVaryingTimeSchedular();
stopSchedular();
} else
{
totalPacketsReceived += 1;
buffer.add(packet);
}
computeToken();
} catch (IOException e)
{
e.printStackTrace();
}
}
public static void computeToken()
{
int bufferSize = buffer.size();
if (bufferSize > 0 && bufferSize < totalBufferCapacity)
{
float queueOccupancy = (bufferSize * 100 / totalBufferCapacity);
} else if (bufferSize == totalBufferCapacity)
{
token = "10";
timesBufferGetsFull += 1;
} else if (token.compareToIgnoreCase("Start") == 0)
{
token = START;
startSchedular();
startVaryingTimeSchedular();
} else
{
totalPacketsDropped += 1;
token = "15";
}
sendAcknowledgment();
}
public static void sendAcknowledgment()
{
try
{
if (ps == null)
{
ps = new PrintStream(clientSocket.getOutputStream());
}
String tokenAck = token;
if (packet.compareToIgnoreCase("Stop") != 0)
{
ps.println(tokenAck);
ps.flush();
}
if (!flag)
{
clientSocket.close();
}
} catch (IOException e)
{
e.printStackTrace();
}
}
public static void startSchedular()
{
rand = (int) (Math.random() * (Max - Min));
timer = new Timer();
task = new consumeArrayItems(true);
timer.scheduleAtFixedRate(task, 1, rand);
}
public static void stopSchedular()
{
timer.cancel();
timer.purge();
flag = false;
}
// After every 500 ms service time of packets will vary between Max and Min
public static void startVaryingTimeSchedular()
{
timer_2 = new Timer();
timer_2.scheduleAtFixedRate(new varyServiceTime(), 0, 500);
}
public static void stopVaryingTimeSchedular()
{
timer_2.cancel();
timer_2.purge();
}
}
class consumeArrayItems extends TimerTask
{
public synchronized void run()
{
if (Receiver.buffer.size() > 0)
{
Receiver.totalPacketsServiced += 1;
Receiver.buffer.remove(Receiver.buffer.size() - 1);
}
}
}
class varyServiceTime extends TimerTask
{
public synchronized void run()
{
Receiver.timer.cancel();
Receiver.timer = null;
Receiver.rand = (int) (Math.random() * (Receiver.Max - Receiver.Min));
Receiver.timer = new Timer();
Receiver.timer.scheduleAtFixedRate(new consumeArrayItems(), 0,Receiver.rand);
Receiver.timesIntervelChanged += 1;
}
}
Timer 2 never gets scheduled. What wrong I am doing here.

Categories