Refering a value in a class which is in same pacakage - java

I have two classes, main and timex. I want to display the value of a variable in my timex class, but I always get the answer 0.
public class mainaxe {
public static void main (String arg[]) {
timex n = new timex();
int n2 = timex.a;
n.timedel();
for(int i=0; i<20; i++) {
System.out.println("the time is :" + n2);
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {}
}
}
}
And this is my timex class:
public class timex extends Thread{
public static int a;
public int timedel(){
for(int i=0; i<200; i++) {
try {
Thread.sleep(1000);
a = a + 5;
}
catch (InterruptedException e){}
// start();
}
return a;
}
}
I want to get the value from the timex class and use it in my main class to print the value for every 1 sec.

I guess you need something like,
Mainaxe.java
package mainaxe;
public class Mainaxe {
public static void main(String arg[]) {
Timex n = new Timex();
n.start();
// int n2 = Timex.a;
// n.timedel();
for (int i = 0; i < 20; i++) {
System.out.println("the time is :" + Timex.a);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
}
}
Timex.java
package mainaxe;
public class Timex extends Thread {
public static int a;
public Timex() {
super();
}
#Override
public void run() {
timedel();
}
public int timedel() {
for (int i = 0; i < 200; i++) {
try {
Thread.sleep(1000);
a = a + 5;
} catch (InterruptedException e) {
}
// start();
}
return a;
}
}

If you want a multi-threaded program, then in your class that extends Thread, declare a method exactly like this:
#Override
public void run () {
// in here, put the code your other thread will run
}
Now, after you create a new object of this class:
timex n = new timex();
you have to start the thread like this:
n.start();
This causes the object to start running its run method in a new thread. Having your main thread call other methods in n won't do anything with the new thread; any other method called by the main thread will be performed in the main thread. So you can't communicate with the new thread with a function call. You have to do it with other means, such as you were trying to do with your variable a.

Related

How do I instantiate two threads of the same object, and have the objects print different things

The goal: So I have a runnable class ThisThat. I instantiate two threads of ThisThat. One prints "This" and one prints "That". The main class is not supposed to determine what it prints.
The question: how do I make a default constructor set two different outputs for two threads of the same class? What can be improved? How can I make it only print this or that instead of both simultaneously?
Desired end result would be a program that runs for about 10 seconds and prints either this or that 10 times. Current output is "this" "that" at the same time, waits about 10 seconds and then repeats 10 times.
import java.util.Random;
public class ThisThat implements Runnable {
private String output;
private int threadNum;
public ThisThat() {
output = "";
}
public ThisThat(int t_Num) {
threadNum = t_Num;
setThisOrThat(threadNum);
}
public void setThisOrThat(int num) {
if (num == 1) {
output = "this";
} else if (num == 2) {
output = "that";
} else {
Random random = new Random();
int randNum = random.nextInt((3) + 1);
setThisOrThat(randNum);
}
}
#Override
public void run() {
for (int i=1; i <= 10; i++) {
try {
System.out.println(getOutput());
Thread.sleep((int)(800));
}
catch(InterruptedException e) {
System.err.println(e);
}
}
}
public String getOutput() { return output; }
public void setOutput(String output) { this.output = output; }
}
class Main {
public static void main(String args[]) {
Thread thread1 = new Thread(new ThisThat(1));
Thread thread2 = new Thread(new ThisThat(2));
thread1.start();
thread2.start();
}
}
One solution is to update the constructor to not take in anything from Main, then create a static volatile or Atomic property within your ThisThat class that is basically a counter changing the values for each thread instance.

Sequential thread execution using wait/notify

Now I'm struggling with the task from the title. I create X threads, each of them prints Y equal digits (getting from constructor, for example "11111", "222222" etc) for Z times in cycle. So the result looks like:
111111111
222222222
333333333
111111111
222222222
333333333
for X = 3, Y = 9 and Z = 2.
Firstly I've solved this issue using sleep, interrupt and passing "next" thread to the constructor of previous one. One interrupts another etc. Next step is to get the same output using wait/notify instead sleep and interrupt. As far as I can see, it's neccesary to create the shared monitor object, to invoke wait after every printing and in a some moment " I should invoke notifyAll.
Current code is:
public class PrinterController {
private static final int THREADS_NUMBER = 5;
public static void main(String[] args) {
Printer[] printers = new Printer[THREADS_NUMBER];
for (int i = 0; i < THREADS_NUMBER; i++) {
printers[i] = new Printer(i);
printers[i].start();
}
}
}
public class Printer extends Thread {
private static int portion = 10;
private static int totalNumber = 100;
private int digit;
private static final Object monitor = new Object();
public Printer(int digit) {
this.digit = digit;
}
#Override
public void run() {
synchronized (monitor) {
int portionsNumber = totalNumber / portion;
for (int i = 0; i < portionsNumber; i++) {
printLine();
try {
monitor.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private void printLine() {
for (int j = 0; j < portion; j++) {
System.out.print(digit);
}
System.out.println();
}
}
Could you help to improve it? I found similar tasks but they don't contain appropriate answers. Thanks.
Final solution based on the Nadir's answer:
public class Printer extends Thread {
private static int portion = 10;
private static int totalNumber = 100;
private int digit;
static Object monitor = new Object();
static Integer counter = 0;
public Printer(int digit) {
this.digit = digit;
}
#Override
public void run() {
int portionsNumber = totalNumber / portion;
for (int i = 0; i < portionsNumber; i++) {
synchronized (monitor) {
while (digit != counter) {
try {
monitor.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
printLine();
monitor.notifyAll();
}
}
}
private void printLine() {
for (int j = 0; j < portion; j++) {
System.out.print(digit);
}
System.out.println();
counter = (counter + 1) % PrinterController.THREADS_NUMBER;
}
}
It can be accomplished with a class used to synchronize the threads (and even make sure they are orderer). All threads would share the same instance.
public class Synchronizer
{
private int nextThread;
private int maxNumThreads;
public Synchronizer(int numThreads)
{
maxNumThreads = numThreads;
nextThread = 0;
}
public void doSync(int threadId) throws Exception
{
synchronized(this)
{
while(nextThread != threadId)
{
wait();
}
}
}
public void threadDone(int threadId) throws Exception
{
synchronized(this)
{
nextThread = (threadId + 1) % maxNumThreads;
notifyAll();
}
}
}
On your thread's run(), you would call doSync() before printing anything. Then you would put the code for printing, and afterwards, you would call threadDone(), allowing the next thread to be released. The id is used to enforce an order.

Thread safe read/write to a counter

Im trying to make 2 threads that read/write to a counter using thread safe methods.
I have written some code to try test this but the read thread just reads the counter at its max (1000)
Main:
public static void main(String[] args) {
Counter c = new Counter();
Thread inc = new Increment(c);
Thread read = new Read(c);
inc.start();
read.start();
}
Counter:
public class Counter {
private int count;
public Counter() {
count = 0;
}
public synchronized void increment() {
count++;
}
public synchronized int getVal() {
return count;
}
}
Increment:
public class Increment extends Thread {
private static final int MAX = 1000;
private Counter myCounter;
public Increment(Counter c) {
myCounter = c;
}
public void run() {
for (int i = 0; i < MAX; i++) {
myCounter.increment();
}
}
}
Read:
public class Read extends Thread {
private static final int MAX = 1000;
private Counter myCounter;
public Read(Counter c) {
myCounter = c;
}
public void run() {
for (int i = 0; i < MAX; i++) {
System.out.println(myCounter.getVal());
}
}
}
Would I be better off using Atomic Integer to hold the value of the counter to allow me to safely increment it and get the value?
Your code is perfectly fine as is. It just so happened that your increment thread finished all its increments before the read thread got a chance to read. 1,000 increments takes almost no time at all.
If you want interleave execution of Read thread and Increment thread much more often then the natural operating system thread pre-emption, just make each thread give up their lock (by calling <lockedObject>.wait() followed by <lockedObject>.notify() or notifyAll() in the respective run() methods:
[In Reader]:
public void run() {
for (int i = 0; i < MAX; i++) {
synchronized (myCounter) {
System.out.println(myCounter.getVal());
try {
myCounter.wait(0L, 1);
myCounter.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
[In Increment]:
public void run() {
for (int i = 0; i < MAX; i++) {
synchronized (myCounter) {
myCounter.increment();
try {
myCounter.wait(0L, 1);
myCounter.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Upping the MAX constant to 1_000_000_000 (1 billion) made the treads interleave as well every now and then (on my machine interleave happened just by gazing at few printouts between 150 and 400_000 iterations).

Multithreading doesn't work. What is incorrect?

It's a little program written with a purpose of studying multithreading. I expected to get in main method different random numbers after run. About 4 numbers per second. But I got many thousands of zeros. Where is an error?
Main Class:
public class Main {
public static void main(String[] args) {
ExternalWorld externalWorld = new ExternalWorld();
externalWorld.start();
int x = 0;
while (true) {
while(!externalWorld.signal){
System.out.println("qqq");}
System.out.println(++x + ") " + externalWorld.getAnInt());
}
}
}
ExternalWorld Class:
import java.util.Random;
public class ExternalWorld extends Thread {
private int anInt = 0;
public boolean signal = false;
#Override
public void run() {
Random random = new Random(100);
while(true) {
anInt = random.nextInt(100);
signal = true;
try {
Thread.sleep(200);
signal = false;
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public int getAnInt() {
if (!signal) {
int p = 1 / 0;
}
int result = anInt;
anInt = 0;
return result;
}
}
problem:
private int anInt = 0;
public boolean signal = false;
You are access those variables from one thread to another thus giving you 0 and false on the main thread
solution:
use volatile keyword to access those variables from multiple threads
sample:
private volatile int anInt = 0;
public volatile boolean signal = false;

java.lang.NoSuchFieldException

Our professor assigns us exercises through the jarpeb sytsem (Java Randomised and Personalised Exercise Builder). So the variables names are random.
public class Eczema extends Thread {
private int aurite;
private int[] serlvulate;
public Eczema(int[] serlvulate) {
this.serlvulate = serlvulate;
}
public int getAurite () {
return aurite;
}
#Override
public void run () {
try {
aurite = Integer.MAX_VALUE;
for (int i = 0; i < serlvulate.length; i++) {
if (i < this.aurite) {
this.aurite = i;
sleep (1000);
}
}
} catch (InterruptedException e) {
System.out.println("Found an Exception!");
return;
}
}
}
public class Stub {
public static int polytoky (int[]a, int[]b) throws InterruptedException {
Eczema Eczema1 = new Eczema (a);
Eczema Eczema2 = new Eczema (b);
Eczema1.start();
Eczema1.join();
Eczema2.start();
Eczema2.join();
return Math.min (Eczema1.getAurite(), Eczema2.getAurite());
}
}
I followed the instructions of the exercise but when I chech it on the cmd the following error occurs:
Field servulate not found: java.lang.NoSuchFieldException: servulate.
Any ideas how I fix it?
You appear to be accessing a field named servulate while the proper field name is serlvulate. Find the line where this happens and fix the spelling.

Categories

Resources