I'm very new to Thread. I'm trying to understand how to apply the usage of threading by making a simple program. It doesn't seem to be working. The program just ask for two inputs and terminate right away after assigning value to those two variables. Moreover, it throws NullPointerException if the threadNum variable is more than 1 Could you please explain the proper way to do this?
Also, I'm confused about constructing and starting a thread with new Thread(this).start();
package helloworld;
import java.util.Scanner;
public class HelloWorld implements Runnable {
private int threadNum;
private int taskNum;
private int loopNum;
public HelloWorld(int threadNum, int taskNum){
this.taskNum = taskNum;
this.threadNum = threadNum;
int loop = taskNum / threadNum;
this.loopNum = loop;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Task Num = ");
int taskNum = sc.nextInt();
System.out.print("Thread Num = ");
int threadNum = sc.nextInt();
HelloWorld hello = new HelloWorld(threadNum, taskNum);
hello.activate();
}
public void activate(){
Thread[] a = new Thread[this.threadNum];
int count = 0;
for(Thread x : a){
x = new Thread(this);
}
for(int i = 0; i < a.length - 1 ; i++){
while(count < loopNum){
a[i].start();
count++;
}
count = 0;
while(count < taskNum - ((threadNum - 1) * loopNum)){
a[a.length - 1].start();
count ++;
}
}
}
#Override
public void run() {
System.out.println("Processing....");
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println("Done !!");
}
}
HelloWorld implements Runnable means new Thread(this) is passing a Runnable to the constructor of Thread. You aren't actually filling a in your current code. You can do that like
Thread[] a = new Thread[this.threadNum];
for(int i = 0; i < this.threadNum; i++){
a[i] = new Thread(this);
}
// Now `a` is filled with threads.
int count = 0;
Related
I have to insert the elements using three threads by creating three classes, namely Task1,Task2 and Task3. The values to be inserted into the array are 0,1,2,....299.
Override the run method in the threads. Three integer i,j, and k representing the number of elements each thread should append inside the given array.
Thread one should append 0 to i-1 inside the array,thread two should append i to i+j-1 inside the array,and the third thread should append i+j to 299 inide the array.
Threads one and two must run simultaneously, and the values of the threads one and two must be inserted inside the indices of the array from 0 to i+j-1 randomly.The third thread should start only after the first two threads have been executed completely.
In these code three task are given.
first task and second task start executing the thread at the same time and after completion of first two task then only third task start. If these situation getting correct then test() method return true.
public static final int[] threadArray = new int[300]; how I add random number into these array using Task1 Task2 and Task3 class.
Input :
80
130
90
Output :
True
import java.util.Scanner;
class Task1 extends Thread
{
static int a = 0;
static int beg = 0;
public void run()
{
for(int i=a;i<=beg;i++)
{
Solution.threadArray[i] = i;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class Task2 extends Thread
{
static int a = 0;
static int beg = 0;
#Override
public void run()
{
// TODO Auto-generated method stub
for(int i=a;i<=beg;i++)
{
Solution.threadArray[i] = i;
}
}
}
class Task3 extends Thread
{
static int a = 0;
static int beg = 0;
public void run()
{
// TODO Auto-generated method stub
for(int i=a;i<=beg;i++)
{
Solution.threadArray[i] = i;
}
}
}
public class Solution
{
public static final int[] threadArray = new int[300];
public static volatile String i = 0+"";
public boolean test() throws InterruptedException
{
Task1 task1 = new Task1();
Task2 task2 = new Task2();
Task3 task3 = new Task3();
Thread task2Thread = new Thread(task2);
Thread task3Thread = new Thread(task3);
task1.start();
task2Thread.start();
task1.join();
task2Thread.join();
task3Thread.start();
int first = Task1.a+Task2.a;
int containsSecondThread = Task1.a;
String oneAndTwo = "";
String sizeOfTask1 = "";
for(int i=0;i<first;i++)
{
oneAndTwo += threadArray[i]+" ";
}
for(int i=0;i<containsSecondThread;i++)
{
sizeOfTask1 += threadArray[i]+" ";
}
int begOfTask3 = Task3.beg;
String checkingString = "";
for(int i=begOfTask3;i<threadArray.length;i++)
{
checkingString += i + " ";
}
String task3String = "";
for(int j = begOfTask3;j<threadArray.length;j++)
{
task3String += threadArray[j]+" ";
}
if((!oneAndTwo.contains(begOfTask3+"") && sizeOfTask1.contains(Task2.beg+"")) || task3String.equals(checkingString))
{
return true;
}
return false;
}
public static void main(String[] args) throws InterruptedException
{
Scanner sc= new Scanner(System.in);
Solution solution = new Solution();
int one = sc.nextInt();
Task1.a = one;
Task1.beg = 0;
int two = sc.nextInt();
Task2.a = two;
Task2.beg = one;
int three = sc.nextInt();
Task3.a = three;
Task3.beg = one+two;
System.out.print(solution.test());
}
}
First, some observations regarding your code: Instead of using static variables in the classes (i.e., Task1, Task2, and Task3) that extend the class Thread (to understand why have a look at Why are static variables considered evil?):
static int a = 0;
static int beg = 0;
use non-static final fields, and initialize them via the constructor:
class Task1 extends Thread
{
private final int begin;
private final int end;
Task1(int begin, int end){
this.begin = begin;
this.end = end;
}
public void run(){
for(int i=begin; i<= end; i++)
....
}
}
adapt the main method accordingly:
public static void main(String[] args){
...
Task1 task1 = new Task1(begin, end);
}
and then pass the tasks-related objects as parameters of to the test method:
public boolean test(Task1 task1, Task2 task2, Task3 task3){
...
}
For the concatenation of the strings use StringBuilder:
StringBuilder oneAndTwo = new StringBuilder();
for(int i=0;i<first;i++)
{
oneAndTwo.append(threadArray[i]).append(" ");
}
This looks wrong:
Task1.a = one;
Task1.beg = 0;
by looking at the loop of the run method from Task1, this means that, if Task1.a is not a negative number, then Task1 will not do any work.
To use the threads to generate the random values of the array:
int[] threadArray = new int[300];
you can start by extracting a method to generate those random values, based on formula:
r.nextInt(high-low) + low;
this formula generates a random value between low and high.
Adapt the tasks, accordingly:
class Task1 extends Thread
{
private final Random random_values = new Random();
private final int low;
private final int high;
...
public int generate_random(){
return r.nextInt(high-low) + low;
}
public void run()
{
for(....)
{
Solution.threadArray[i] = generate_random();
...
}
}
}
Make sure to pass to the threads the information about the range of the random values to be generated (i.e., the low and high parameters), and the reference to the array that will be filled up with those random values (i.e., array int[] threadArray) . Also make sure that you split the iterations int[] threadArray among the threads. Therefore, each thread should generate a chunk of the random values. An example of such distribution would be:
Thread 1 : 0 to 100;
Thread 2 : 100 to 200;
Thread 3 : 200 to 300;
You can make this more robust and divide the array length by the number to threads and assign the work among threads, accordingly.
I could have provided you with the entire solution, but I feel that is better instead if I give you the pointers so that you can do it in your own.
EDIT: Based on the new edit of your question:
You just need to adapt the Task classes as follows:
class Task1 extends Thread {
static int a = 0;
static int beg = 0;
public void run(){
for(int i=beg;i < a;i++)
Solution.threadArray[i] = i;
}
}
class Task2 extends Thread {
static int a = 0;
static int beg = 0;
public void run(){
for(int i=beg; i< beg + a;i++)
Solution.threadArray[i] = i;
}
}
class Task3 extends Thread{
static int a = 0;
static int beg = 0;
public void run(){
for(int i=beg;i< a + beg;i++)
Solution.threadArray[i] = i;
}
}
Thread1 and Thread2 are supposed to access Common Resource in threadArray[0... Task1.a+Task2+a]. So we have to make use of static volatile variable i declared in Solution Class.
class Task1 extends Thread
{
static int a=0,beg=0;
public void run()
{
int k=Task1.beg;
int i1=0;
while(i1<Task1.a)
{
Solution.threadArray[Integer.parseInt(Solution.i)]=k++;
int a1=Integer.parseInt(Solution.i);
a1++;i1++;
Solution.i=a1+"";
try{
Thread.sleep(1);
}
catch(InterruptedException e){}
}
}
}
class Task2 extends Thread
{
static int a=0,beg=0;
public void run()
{
int y=0;
int k=Task2.beg;
while(y<Task2.a)
{
Solution.threadArray[Integer.parseInt(Solution.i)]=k++;
int a1=Integer.parseInt(Solution.i);
a1++;y++;
Solution.i=a1+"";
try{
Thread.sleep(1);
}
catch(InterruptedException e){}
}
}
}
Thread3 work independently after First 2 threads complete.
class Task3 extends Thread
{
static int beg=0,a=0;
public void run()
{
for(int i=Task3.beg;i<Task3.beg+Task3.a;i++)
{
Solution.threadArray[i]=i;
}
}
}
public class UnsynchronizedCounterTest{
/**
* A class representing a counter with a method for incrementing the coutner. No synchronization is used
* so this counter is not thread safe
* #author
*
*/
static class Counter{
int count;
void inc() {
count = count+1;
}
int getCount() {
return count;
}
}
static Counter counter; // The counter that will be incremented. Since it is a global static variable, it is used by all threads of type HWUExercise12_1Thread. It is shared resource
static int numberOfIncrements;
static class IncrementerThread extends Thread{
public void run() {
for (int i=0; i < numberOfIncrements; i++) {
counter.inc();
}
}
}
/**
* The main program runs in a loop until the user want to exit. Each time through the loop, it runs one experiemtn.
* It gets the number of threads and the number of increments per thread from the user. It creates and starts the
* threads, and then waits for all to finsih. It prints the fibna lvalue of the counter, as well as the expected value.
* The program ends when the user enters a number less than or equal to zero as the number of threads.
* #param Args
*/
public static void main(String Args[]){
Counter counter = new Counter();
Scanner reader = new Scanner(System.in);
while(true) {
System.out.print("Enter the number of threads");
int numberOfThreads = Integer.parseInt(reader.nextLine());
if (numberOfThreads < 0) {
break;
}do {
System.out.print("Enter the number of increments per thread");
int numberOfIncrements = reader.nextInt();
//create thread array
IncrementerThread [] threads = new IncrementerThread[numberOfThreads];
//Create a thread for each position in array
for (int i=0; i< threads.length; i++) {
threads[i] = new IncrementerThread();
}
}while (numberOfIncrements <= 0);
//start the threads
for (int i=0; i < numberOfThreads; i++) {
threads[i].start();
}
try {
for(int j=0; j< numberOfThreads; j++) {
threads[j].join();
}
System.out.println("The finanl value of the counter is" + counter.getCount());
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
For this program, I created a thread class (not thread-safe) that calls the inc () method in the nested class, a specified number of times. My program is supposed to create several threads and start them all and then wait for all the threads to terminate. I also have to print the final value of the counter. My error is that the eclipse is saying the the thread array I created, threads cannot be resolved to a variable. It's giving me an error for the lines
threads[i].start();
threads[j].join();
I'm a beginner in java and I'm not sure how to fix this issue. My question is that why is it saying threads cannot be resolved to a variable when I clearly have a thread object array? Thanks.
This is a working code:
public class UnsynchronizedCounterTest{
static Counter counter;
public static void main(String Args[]){
new UnsynchronizedCounterTest().startCounting();
}
public void startCounting() {
counter = new Counter();
Scanner reader = new Scanner(System.in);
while(true) {
System.out.print("Enter the number of threads: ");
int numberOfThreads = reader.nextInt();
if (numberOfThreads <= 0) {
break;
}
IncrementerThread [] threads;
do {
System.out.print("Enter the number of increments per thread");
numberOfIncrements = reader.nextInt();
//create thread array
threads = new IncrementerThread[numberOfThreads];
//Create a thread for each position in array
for (int i=0; i< threads.length; i++) {
threads[i] = new IncrementerThread();
}
}while (numberOfIncrements <= 0);
//start the threads
for (int i=0; i < numberOfThreads; i++) {
threads[i].start();
}
try {
for(int j=0; j< numberOfThreads; j++) {
threads[j].join();
}
System.out.println("The finanl value of the counter is: " + counter.getCount());
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
class IncrementerThread extends Thread{
#Override
public void run() {
for (int i=0; i < numberOfIncrements; i++) {
counter.inc();
}
}
}
class Counter{
int count = 0;
void inc() {
count = count+1;
}
int getCount() {
return count;
}
}
}
I'm trying to make a "X and O" game using threads. I use a char matrix[3][3] for my game table and I want the first thread to put "X" and after that to show the matrix and then the second threat to pun "O" and so on. How can I do this using threads?
public class ThreadExample implements Runnable {
private char[][] array;
private Semaphore ins, outs;
private int counter;
ThreadExample(Semaphore ins, Semaphore outs) {
this.ins = ins;
this.outs = outs;
this.counter = 0;
this.array = new char[3][3];
}
#Override
public void run() {
for (int i = 0; i < 9; i++) {
try {
ins.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
} // wait for permission to run
print();
playTurn();
outs.release(); // allow another thread to run
}
}
private void print() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
System.out.print(array[i][j] + " ");
}
System.out.println();
}
}
private synchronized void playTurn() {
Scanner sc = new Scanner(System.in);
int x;
int y;
System.out.println("enter the x coord: ");
x = sc.nextInt();
System.out.println("enter the y coord: ");
y = sc.nextInt();
// sc.close();
if (counter % 2 == 0) {
array[x][y] = 'X';
counter++;
} else {
array[x][y] = 'O';
counter++;
}
}
}
And this is my main
public class Main {
public static void main(String[] args) {
Semaphore a = new Semaphore(1);
Semaphore b = new Semaphore(0);
ThreadExample th1 = new ThreadExample(a, b);
Thread tr1 = new Thread(th1);
Thread tr2 = new Thread(th1);
tr1.start();
tr2.start();
}
}
This is my code so far but after the first x and y coord it stops.
The problem is here, after the first 'x,y' both threads are waiting for the 'ins' Semaphore, and no one cares about the 'outs'.
You can fix it by remove 'outs' and use only 'ins'. Here you should double check, that how acquire is implemented. Does it grantee a queue or can a thread acquire it twice rarely?
I'm trying to do a simple program that ask you to remember 30 numbers after 3 minutes. I have done everything, also the timer, in the examples I put 5 seconds. But I don't know how to save in memory the numbers, because the array that contains them is in another class. To create the timer I found this method, but not sure if is correct. So at the end of the program I get the array generated from the pc that is empty and the result is to lose all the points.
public class Test {
// variables for the class
int[] Array = new int[30];
int ArrayNumUser[] = new int[30];
int x;
public static Test R = new Test();
Timer timer;
static Scanner scan = new Scanner(System.in);
static String verifica;
char p;
// Constructor timer
public Test(int seconds) {
timer = new Timer();
timer.schedule(new NumUser(), seconds * 1000);
}
public Test() {
}
// Generate numbers with an array
public String GenerateNum() {
for (int i = 0; i < Array.length; i++) {
x = (int) (Math.random() * (10 - 0) + 0);
Array[i] = x;
}
System.out
.println("Rember this numbers, you got 3 minutes to complite the challenge");
return Arrays.toString(Array);
}
// Save the numbers in an array
public class NumUser extends TimerTask {
public void run() {
int y;
System.out.println("Insert the numbers you remember..");
for (int i = 0; i < ArrayNumUser.length; i++) {
System.out.println("Insert the number: " + (i + 1));
y = scan.nextInt();
ArrayNumUser[i] = y;
}
// Check the numbers are equals to the arrays given
System.out.println("Enter 'x' to confirm");
String ver = scan.next();
char confirm = ver.charAt(0);
if (confirm == 'x') {
int points = 0;
for (int i = 0; i < Array.length; i++) {
int p = Array[i];
int t = ArrayNumUser[i];
if (p == t) {
points++;
} else
points--;
}
System.out.println("Yours points: " + points);
System.out.println(Arrays.toString(Array));
System.out.println(Arrays.toString(ArrayNumUser));
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
R.GenerateNum();
new Test(5);
}
}
Do it other way:
1. in Test() constructor generate array,
2. write schedule method in test which schedules timer
public Test() { GenerateNum(); }
public void schedule(int sec) {
timer = new Timer();
timer.schedule(new NumUser(), seconds * 1000);
}
public static void main(String[] args) {
new Test().schedule(5);
}
class SelfishRunner extends Thread{
private int tick = 1;
private int num ;
public SelfishRunner(int x){
this.num = x;
}
#Override
public void run(){
try{
while(tick < 400000){
Thread.sleep(250);
if((tick%50000) == 0){
System.out.println(" Thread# "+num+","+Thread.currentThread().getName()+", tick "+tick);
}
tick++;
}
}catch(Exception e){
System.out.println(e);
}
}
}
public class RaceDemo{
private final static int NUMRUNNERS = 2;
public static void main(String[] args){
SelfishRunner[] runners = new SelfishRunner[NUMRUNNERS];
for(int x=0,y=1; x < NUMRUNNERS; x++){
runners[x] = new SelfishRunner(x);
runners[x].setPriority(y++);
}
runners[0].setName("JEEPERS");
runners[1].setName("KREEPERS");
for(int x=0; x < NUMRUNNERS; x++){
runners[x].start();
}
}
}
The above code is trying to create a race condition, but in SelfRunner.run the call to Thread.sleep(250) halts program execution without printing output to the command line.
When I comment out that line, it works fine.
Can anybody tell me why?
You do realize that you are only printing something every 50000/4 seconds, right? You might want to wait a little bit longer. :)