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?
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;
}
}
}
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;
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;
}
}
}
This question already has answers here:
Write int to text file using Writer
(8 answers)
Closed 5 years ago.
This is my code and I want b[i] will be write to the file name test.txt but it is not working. It's just write something like symbols. Thanks for helping.
public class btl {
public static boolean IsPrime(int n) {
if (n < 2) {
return false;
}
int squareRoot = (int) Math.sqrt(n);
for (int i = 2; i <= squareRoot; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
public static void main(String args[]) {
Scanner scanIn = new Scanner(System.in);
int first = 0;
int second = 0;
try {
System.out.println("Input First Number");
first = scanIn.nextInt();
System.out.println("Input Second Number");
second= scanIn.nextInt();
}
catch(Exception e) {
System.out.println("Something wrong!");
}
int x = first;
int y = second;
int a;
int[] b = new int[y];
Thread threadA = new Thread(new Runnable() {
#Override
public void run() {
int c=0;
for(int i=x; i<y; i++) {
if(IsPrime(i)) {
b[c] = i;
System.out.println(b[c]);
c++;
}
}
}
});
threadA.start();
try(FileWriter fw = new FileWriter("test.txt")){
for(int i =0; i<y; i++)
{
fw.write(b[i]);
}
}
catch(IOException exc) {
System.out.println("EROR! " + exc);
}
}
}
This is my display console
And this is file "test.txt"
I don't know why FileWriter writes symbols in file text.txt. I want it's number of array b[i].
FileWriter.write(int) writes a single character.
You likely want FileWriter.write(String)as in:
fw.write(Integer.toString(b[i]));
I know it means the reference to the array is volatile not the items in the array if you declare an array volatile.
I am learning mutex algorithm, so I write some test code:
public class MutualExclusion {
static final int N = 10;
static final int M = 100000;
volatile static int count = 0;
public static void main(String[] args) {
Thread[] threads = new Thread[N];
for (int i = 0; i < N; i++) {
Thread t = new Worker(i);
threads[i] = t;
t.start();
}
for (Thread t: threads) {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (count != N * M) {
System.out.println("count (" + count + ") != N * M (" + String.valueOf(N * M) + ")");
}
}
static class Worker extends Thread {
int id;
Worker(int id) {
this.id = id;
}
#Override
public void run() {
for (int i = 0; i < M; i++) {
this.lock();
// critical section
count++;
if (i % 1000 == 0) {
System.out.println(this.getName() + ": " + count);
}
this.unlock();
}
}
void lock() {
filterLock();
}
void unlock() {
filterUnlock();
}
static volatile int level[] = new int[N];
static volatile int lastToEnter[] = new int[N - 1];
void filterLock() {
for (int i = 0; i < (N - 1); i++) {
level[this.id] = i;
lastToEnter[i] = this.id;
outer:
while (lastToEnter[i] == this.id) {
for (int k = 0; k < N; k++ ) {
if (k != this.id && level[k] >= i) {
continue outer;
}
}
break;
}
}
}
void filterUnlock() {
level[this.id] = -1;
}
}
}
In my first implementation of filter algorithm, I missed volatile for variable level and lastToEnter, not surprisingly, the program went into a infinite loop. After I added the missing volatile, the program can end as expected.
As I said in beginning, a volatile array doesn't mean items in the array are volatile, so why can the program end as expected after I added the missing volatile?
I asked myself this question when I was implementing another mutex algorithm which still doesn't run correctly after I added volatile keyword. I have to use a trick (Java volatile array?) to make items in the array looks like being volatile: (code below can be pasted into Worker class directly)
volatile static boolean[] b = new boolean[N];
volatile static boolean[] c = new boolean[N];
volatile static int k = 0;
void dijkstraLock() {
b[this.id] = false;
outer:
for (;;) {
if (k == this.id) {
c[this.id] = false;
c = c; // IMPORTANT! the trick
for (int i = 0; i < N; i++) {
if (i != this.id && !c[i]) {
continue outer;
}
}
break;
} else {
c[this.id] = true;
if (b[k]) {
k = this.id;
}
}
}
}
void dijkstraUnlock() {
b[this.id] = true;
c[this.id] = true;
}
Volatile arrays in Java do not contain volatile elements - but if you access them via the array reference (which is volatile) you will get a volatile read. For instance, in the code above:
static volatile int lastToEnter[] = new int[N - 1];
is a volatile write, whereas
lastToEnter[i] = this.id;
is not. however, the evaluating of the array value - such as:
lastToEnter[i] == this.id
is a volatile read - you first read the reference to the array which is volatile, and only then access the i'th element to evaluate its value.
I suspect this is the reason your execution succeeds once the array is declared as volatile.