Java threads to do different tasks? - java

I am looking at an example which code is:
class SimpleThread extends Thread {
public SimpleThread(String str) {
super(str);
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i + " " + getName());
try {
sleep((int)(Math.random() * 1000));
} catch (InterruptedException e) {}
}
System.out.println("DONE! " + getName());
}
}
and
class TwoThreadsTest {
public static void main (String args[]) {
new SimpleThread("Jamaica").start();
new SimpleThread("Fiji").start();
}
}
My question is: is there a way each thread does its own code? For example, one thread increments a variable, while the other thread increments other variable.
Thanks.
P.S. Example's link is: http://www.cs.nccu.edu.tw/~linw/javadoc/tutorial/java/threads/simple.html

Each instance of SimpleThread has it's own local class storage. As long as you aren't using fields marked as static, then each thread will "do its own code". It is much harder to synchronize values between threads.
For example:
class SimpleThread extends Thread {
// this is local to an _instance_ of SimpleThread
private long sleepTotal;
public SimpleThread(String str) {
super(str);
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i + " " + getName());
try {
long toSleep = Math.random() * 1000;
// add it to our per-thread local total
sleepTotal += toSleep;
sleep(toSleep);
} catch (InterruptedException e) {}
}
System.out.println("DONE! " + getName());
}
}

Im new to Java and threads myself but you can do something like this (which may not be very efficient) but using an if statement to check the id or getName() of the thread and if it .equals the name of the particular thread then do this etc
so something like this:
int i;
int j;
if ("thread 2".equals(Thread.currentThread().getName())){
i++;
System.out.println("this is thread 2");
}
else {
j++;
...
}
This should allow you to make the threads run different tasks under the same run() method

Related

Why is it important to make fields private when working with concurrency?

I'm reading Thinking in JAVA (Ed4, by Bruce Eckel), which says:
Note that it’s especially important to make fields private when
working with concurrency; otherwise the synchronized keyword cannot
prevent another task from accessing a field directly, and thus
producing collisions.
I am confused and finally get this demo:
public class SimpleSerial {
public static void main(String[] args) throws IOException {
ShareObject so = new ShareObject();
Thread thread1 = new Thread(new ThreadOperation(so, "add"));
Thread thread2 = new Thread(new ThreadOperation(so, "sub"));
thread1.setDaemon(true);
thread2.setDaemon(true);
thread1.start();
thread2.start();
System.out.println("Press Enter to stop");
System.in.read();
System.out.println("Now, a=" + so.a + " b=" + so.b);
}
}
class ThreadOperation implements Runnable {
private String operation;
private ShareObject so;
public ThreadOperation(ShareObject so, String oper) {
this.operation = oper;
this.so = so;
}
public void run() {
while (true) {
if (operation.equals("add")) {
so.add();
} else {
so.sub();
}
}
}
}
class ShareObject {
int a = 100;
int b = 100;
public synchronized void add() {
++a;
++b;
}
public synchronized void sub() {
--a;
--b;
}
}
Every time the values of a and b are different. So why?
The demo also mentioned if the thread sleep() for short time, i.e., re-write the run() method in ThreadOperation:
public void run() {
while (true) {
if (operation.equals("add")) {
so.add();
} else {
so.sub();
}
try {
TimeUnit.MILLISECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
then values of a and b are the same.
So again, Why? What happens behind sleep()?
With sleep() it becomes probable that the println() executes while the threads are sleeping. The program is still very not thread-safe.
You could fix it by adding a synchronized print() method to SharedObject eg:
public synchronized void print() {
System.out.println("Now, a=" + a + " b=" + b);
}
and calling that on the last line of main instead of the current unsynchronized accesses.

My own semaphore in java

I'd like to implement my own semaphore in Java (just for practice, I am aware, that there is Semaphore class)
I have implemented it like that:
public class MySemaphore {
private int value = 1;
public synchronized void take() {
this.value++;
this.notify();
}
public synchronized void release(){
while (this.value == 0) {
try {
wait();
} catch (InterruptedException e) {
}
}
this.value--;
}
}
I am trying to use it in such thread:
public class MyThread extends Thread {
private static MySemaphore semaphore = new MySemaphore();
public void run(){
for (int i = 0; i < 100; i++) {
semaphore.take();
try {
Main.myVariable += 1;
semaphore.release();
} catch (Exception e){
System.out.println("Exception" + e.getMessage());
}
}
}
}
I start and join threads like this:
import java.util.ArrayList;
import java.util.List;
public class Main {
public static int myVariable = 0;
private static int threadsNumber = 100;
public static void main(String[] args) {
List<Thread> allThreads = new ArrayList<>();
for (int i = 0; i < threadsNumber; i++) {
allThreads.add(new Thread(new MyThread()));
}
for (int i = 0; i < threadsNumber; i++) {
allThreads.get(i).start();
}
for (int i = 0; i < threadsNumber; i++) {
try{
allThreads.get(i).join();
} catch (Exception e){
System.out.println(e.getMessage());
System.out.println("********************************");
}
}
System.out.println("Result is " + myVariable);
}
}
I just want to increment a variable 10000 times and receive a result. Without semaphore the result is less than 10000 (like 9923, 9684), which is caused by non-atomicity of incrementation. I want to protect this variable using semaphore.
Unfortunately, the result is still less than or equal to 10000 (but much closer, in 9 out of 10 cases greater than 9990).
Do you have any idea why it happens? Is my semaphore wrong or am doing something wrong with launching threads?
In your MySemaphore class, value is already set to 1. It should be zero because in your release function you are verifying if value equals zero or not. This means that when your program starts, no thread will be able to have the semaphore(because you have set it to 1); doing so, they fall into waiting state. Your program ends when 'threadsNumber' reaches it's limit.In other words, you are not verifying if any thread is in waiting state before the programs ends. This explains why you have a 9/10 as success rate.
My recommendation would be to try setting the value to zero and also verify if there are any threads in waiting state.
Your code be like this:
public class MySemaphore {
private int value = 0; //this is already an error in your code
public synchronized void take() {
this.value++;
this.notify(); // wakes up the first thread that called wait on the shared variable
}
public synchronized void release() throws InterruptedException{
while(this.signals == 0) wait();
this.value--;
}
}

How to simulate a race between threads which run in parallel? [duplicate]

This question already has answers here:
Code to simulate race condition in Java thread
(4 answers)
Closed 6 years ago.
I am trying to make a thread race, but my threads run in order instead of running in parallel ...After a thread finishes the race , it has to inform the context and the context should announce the winner and stop the race . How can I repair this ?
My ThreadRaceClass:
public class ThreadRace {
List<ThreadRaceCompetitor> competitors = new ArrayList<>(10);
public ThreadRace() {
for (int i = 0; i < 10; i++) {
competitors.add(new ThreadRaceCompetitor());
}
}
public void start() {
competitors.forEach(ThreadRaceCompetitor::run);
}
}
The ThreadCompetitor object:
public class ThreadRaceCompetitor implements Runnable {
private static final ThreadRaceContext context = new ThreadRaceContext();
private static AtomicInteger count = new AtomicInteger(0);
private int raceNumber;
private int progress = 0;
public ThreadRaceCompetitor() {
raceNumber = count.incrementAndGet();
}
#Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("Thread " + raceNumber + " is running with " + i + " speed and has covered " + progress + " kilometers / 20" );
try {
sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
progress++;
}
synchronized (context) {
context.announceWinner(raceNumber);
}
}
public int getRaceNumber() {
return raceNumber;
}
public int getProgress() {
return progress;
}
}
And the context:
public class ThreadRaceContext extends Thread {
public void announceWinner(int raceNumber) {
System.out.println("Competitor with number " + raceNumber + " won the race");
}
}
You have to call the start-method. Then it should work.
public void start() {
competitors.forEach(ThreadRaceCompetitor::start); // not sure if that is possible...
}
//alternative
public void start() {
for(ThreadRaceCompetitor c: competitors) {
c.start();
}
}
First of all you are not creating any Thread here. Just by implementing runnable will not make an instance of a class Thread. Using your runnable you have to create an instance of Thread and start it.
One way to achieve this with your existing code is to make your ThreadRaceCompetitor extend Thread and in your ThreadRace class's start method call start method on each ThreadRaceCompetitor in the list instead of calling run directly.

Implementing Runnable Abstract Class--Multi Threading

I want to call two constructors with different parameters, which in turn run their individual thread but the issue is it only allows one run() method, is there anyway i can run two run() method in one class?? or any other solution to such situation?
class Threading implements Runnable {
Thread t;
Thread t1;
String name;
Threading(String s) {
name = s;
t = new Thread(this, name);
System.out.println("Constructor 1: " + t);
t.start();
}
public void run() {
try {
for (int i = 5; i > 0; i--) {
System.out.println("Constructor 1: " + i);
Thread.sleep(2000);
}
} catch (Exception e) {
}
System.out.println("Constructor1 exiting");
}
Threading(int a, int b) {
t1 = new Thread(this, "java2 Thread");
System.out.println("Constructor 2: " + t1);
t1.start();
}
public void run() {
try {
for (int i = 5; i > 0; i++) {
System.out.println("Constructor 2: " + i);
Thread.sleep(3000);
}
} catch (Exception e) {
}
System.out.println("Constructor2 exiting");
}
}
MultipleThread
class MultipleThread {
public static void main(String[] args) {
new Threading("java thread"); // Constructor 1
new Threading(1, 2); // Constructor 2
try {
for (int i = 5; i > 0; i--) {
System.out.println("Print: " + i);
Thread.sleep(1000);
}
} catch (Exception e) {
}
System.out.println("Exit Main");
}
}
There's no reason to implement your Runnable with the same Threading class. You can implement them anonymously within each constructor:
Threading(String s) {
name=s;
t=new Thread(new Runnable() {
#Override
public void run() {
// ...
}
, name);
System.out.println("Constructor 1: "+t);
t.start();
}
You can have a third class called MyThread which implement the Runnable interface and have a constructor with an argument, to save which constructor has created it:
public class MyThread implements Runnable{
private String calledFrom;
public MyThread(String calledFrom){
this.calledFrom = calledFrom;
}
public void run(){
try {
for (int i = 5; i > 0; i++) {
System.out.println(calledFrom + ": " + i);
Thread.sleep(3000);
}
} catch (Exception e) {
}
System.out.println(calledFrom+" exiting");
}
}
Then change your Threading class in a way not to implement Runnable interface. Now in your both constructors, you can have different instances of MyThread class with different arguments: "Constructor 1" and "Constructor 2":
class Threading{
...
Threading(String s) {
name = s;
//t = new Thread(this, name);
MyThread mt = new MyThread("Constructor 1");
System.out.println("Constructor 1: " + t);
//t.start();
mt.start();
}
Threading(int a, int b) {
//t1 = new Thread(this, "java2 Thread");
MyThread mt = new MyThread("Constructor 2");
System.out.println("Constructor 2: " + t1);
//t1.start();
mt.start();
}
}
Passing the "Constructor 2" or "Constructor 1" to the MyThread's constructor is just an example. You can pass some real and useful arguments to MyThread which helps you to separate the implementation by the type or the value of the arguments.
For example you can have two logic method in the MyThread class: logicMethodA() and logicMethodB(), and based on the value of the argument(s) of the constructor, decide to call which one in the run() method.
Hope this would be helpful.

non-synchronized method can access by other thread,,,,,,,

The lock on an object by one thread, no other thread can enter any of the synchronized methods in that class ,but i want to know about non-synchronized method can access by other thread,,,,,,,
class Account {
private int balance = 50;
public int getBalance() {
return balance;
}
public void withdraw(int amount) {
balance = balance - amount;
}
}
public class AccountDanger implements Runnable {
private Account acct = new Account();
public void run() {
for (int x = 0; x < 5; x++) {
this. d();
makeWithdrawal(10);
if (acct.getBalance() < 0) {
System.out.println("account is overdrawn!");
}
}
}
private synchronized void makeWithdrawal(int amt) {
if (acct.getBalance() >= amt) {
System.out.println(Thread.currentThread().getName()
+ " is going to withdraw"+amt);
try {
Thread.sleep(500);
// Thread.sleep(500);
} catch (InterruptedException ex) {
}
acct.withdraw(amt);
System.out.println(Thread.currentThread().getName()
+ " completes the withdrawal"+acct.getBalance());
} else {
System.out.println("Not enough in account for " + Thread.currentThread().getName()
+ " to withdraw " + acct.getBalance());
}
}
public static void main(String[] args) {
AccountDanger r = new AccountDanger();
Thread one = new Thread(r);
Thread two = new Thread(r);
one.setName("Fred");
two.setName("Lucy");
one.start();
two.start();
}
private void d() {
System.out.println("hhhhhhhhhhhhhhhhhhhhh"+Thread.currentThread().getName());
}
}
You have answer in your question itself :). If you are just looking for confirmation : YES.
No lock is required to access non-synchronized methods of an object.
If you want to know more about these concepts, visit Object Locks
Yes, the unsynchronized methods can be accessed/called by any Thread, that has/gets the reference to the same instance. Since you created a private Account instance and you didn't give this instance to any other class, in your example no other thread is able to access this special instance.

Categories