This question already has answers here:
Is multi-thread output from System.out.println interleaved
(4 answers)
Closed 8 years ago.
I have a multithreaded application in Java. In the run method of one of the threads, I have a System.out.println("Print something something something") statement. The problem I have is that sometimes, the output I get from this print is not "Print something something something" but "something Print something something" and some other variations. Please what is the cause of this? The method I am calling in my run method is shown below.
public synchronized void generateRequests() {
String name;
int qty;
int index = 0;
System.out.print("Customer " + custId + " requests, ");
for (Item i : items) {
name = i.getName();
qty = randNoGenerator(0, 10);
items.set(index, new Item(name, qty));
index++;
System.out.print(qty + " " + name + ", ");
}
s.serviceRequests(this);
}
A sample code to understand this problem.
code:
public class MultiThreading implements Runnable {
private String id;
private double qt;
public MultiThreading(String id, double qt) {
this.id = id;
this.qt = qt;
}
public static void main(String[] args) {
MultiThreading obj = new MultiThreading("1", 1000);
for (int i = 0; i < 5; i++) {
// Thread thread = new Thread(new MultiThreading(String.valueOf(i), (i * 1000)));
Thread thread = new Thread(obj);
thread.setPriority(i + 1);
thread.start();
}
}
public synchronized void generateRequests() {
System.out.println("Customer:" + this.id);
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Quentity:" + this.qt);
}
#Override
public void run() {
generateRequests();
}
}
synchronized method is called on same object (This will not mix up the output)
MultiThreading obj = new MultiThreading("1", 1000);
for (int i = 0; i < 5; i++) {
Thread thread = new Thread(obj);
thread.setPriority(i + 1);
thread.start();
}
output:
Customer:1
Quentity:1000.0
Customer:1
Quentity:1000.0
Customer:1
Quentity:1000.0
Customer:1
Quentity:1000.0
Customer:1
Quentity:1000.0
synchronized method is called on different object (This will mix up the output and it may different on next run)
for (int i = 0; i < 5; i++) {
Thread thread = new Thread(new MultiThreading(String.valueOf(i), (i * 1000)));
thread.setPriority(i + 1);
thread.start();
}
output:
Customer:0
Customer:1
Customer:4
Customer:2
Customer:3
Quentity:0.0
Quentity:2000.0
Quentity:3000.0
Quentity:1000.0
Quentity:4000.0
Related
I am trying a write a simple program with wait and notify in which I will create 3 threads.
The first thread should print 1, 2, 3.
The second thread should print 4, 5, 6.
The third thread should print 7, 8, 9.
After that, the first thread should print 10, 11, 12 and so on.
Below is a sample code for the same exercise, but I am unable to print the desired output.
public class MyThread2 extends Thread {
public final static Object obj = new Object();
int threadNo;
static volatile int threadNoToRun;
static volatile int counter = 1;
public MyThread2(int threadNo){
this.threadNo= threadNo;
}
#Override
public void run() {
synchronized (obj) {
try {
if(threadNoToRun != threadNo)
obj.wait();
else{
for(int i = 1 ; i < 4 ; i++){
if(threadNoToRun == threadNo){
System.out.println(threadNo + " counter value is "+counter);
counter++;
System.out.println(threadNo + " counter value is "+counter);
counter++;
System.out.println(threadNo + " counter value is "+counter);
counter++;
if(threadNoToRun == 1){
threadNoToRun = 2;
}
else if(threadNoToRun == 2){
threadNoToRun = 3;
}
else if(threadNoToRun == 3){
threadNoToRun = 1;
}
}
}
obj.notifyAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main (String args[]) {
/*
* Creating as many threads as needed.
*/
MyThread2 th1 = new MyThread2(1);
MyThread2 th2 = new MyThread2(2);
MyThread2 th3 = new MyThread2(3);
MyThread2.threadNoToRun = 1;
th1.start();
th2.start();
th3.start();
}
}
The output looks like:
1 counter value is 1
1 counter value is 2
1 counter value is 3
2 counter value is 4
2 counter value is 5
2 counter value is 6
Here, it was just a few changes.
Nonetheless, I have to point out that this kind of concurrency does NOT increase computation speed. Only one thread is alive at all times.
public class MyThread2 extends Thread {
public final static Object obj = new Object();
int threadNo;
static volatile int threadNoToRun;
static volatile int counter = 1;
public MyThread2(int threadNo) {
this.threadNo = threadNo;
}
#Override
public void run() {
synchronized (obj) {
try {
while (counter < 100) {
if (threadNoToRun != threadNo)
obj.wait();
else {
System.out.println(threadNo + " counter value is " + counter);
counter++;
System.out.println(threadNo + " counter value is " + counter);
counter++;
System.out.println(threadNo + " counter value is " + counter);
counter++;
if (threadNoToRun == 1) {
threadNoToRun = 2;
} else if (threadNoToRun == 2) {
threadNoToRun = 3;
} else if (threadNoToRun == 3) {
threadNoToRun = 1;
}
obj.notifyAll();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String args[]) {
/*
* Creating as many threads as needed.
*/
MyThread2 th1 = new MyThread2(1);
MyThread2 th2 = new MyThread2(2);
MyThread2 th3 = new MyThread2(3);
MyThread2.threadNoToRun = 1;
th1.start();
th2.start();
th3.start();
}
}
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
My task: I need to generate BASE (array) of matrix in multiple threads. It can happen that thread won't make matrix at all so I'm try to limit the lifetime of each thread.
My thought: I made volatile array that contains my matrix generation tasks and made ConcurrentHashMap that contains thread and information class (index in task array and time of thread creation)
My problem: I got NullPointerException when I tried to deal with array
Thread information class:
public class ThreadInformation {
private long timeCreated;
private int automatIndex;
public ThreadInformation (long timeCreated, int automatIndex) {
this.timeCreated = timeCreated;
this.automatIndex = automatIndex;
}
public long getTimeCreated() {
return timeCreated;
}
public int getIndex() {
return automatIndex;
}
}
MultiThread class:
public class MultiTaskGenerator {
private final int BASE_SIZE = 10;
private final Automat[] BASE = new Automat[BASE_SIZE];
private static final int THREAD_COUNT = 8;
private final int THREAD_LIVE_TIME_SEC = 10;
private Map<Thread, ThreadInformation> threads = new ConcurrentHashMap<>();
private volatile GeneratorTask[] tasks = new GeneratorTask[THREAD_COUNT];
private int automatReady = 0;
MultiTaskGenerator() {
getThreadResult();
}
private void initThreads() {
for (int i = 0; i < THREAD_COUNT; i++) {
int j = i;
System.out.println("Thread №" + j + " started");
threads.put(new Thread(() -> {
tasks[j] = new GeneratorTask();
}), new ThreadInformation(System.currentTimeMillis(), j));
}
startThreads();
}
private void initNewThread(int index) {
for (int i = 0; i < tasks.length; i++) {
if (i == index) {
threads.put(new Thread(() -> {
tasks[index] = new GeneratorTask();
}), new ThreadInformation(System.currentTimeMillis(), index));
}
}
}
private void startThreads() {
for (Thread thread : threads.keySet()) {
Thread.State state = thread.getState();
if (state == Thread.State.NEW) {
thread.start();
}
}
}
private void getThreadResult() {
initThreads();
for (int i = 0; i < tasks.length; i++) {
System.out.println(tasks[i]);
}
while (automatReady < BASE_SIZE) {
Set mapSet = threads.entrySet();
Iterator iterator = mapSet.iterator();
while (iterator.hasNext()) {
Map.Entry<Thread, ThreadInformation> mapEntry = (Map.Entry)iterator.next();
if (!mapEntry.getKey().isAlive()) {
if (automatReady == BASE_SIZE) continue;
int currentIndex = mapEntry.getValue().getIndex();
BASE[automatReady] = tasks[currentIndex].getAutomat();
System.out.println("Добавлен автомат № " + automatReady);
automatReady++;
System.out.println("Thread №" + mapEntry.getValue().getIndex() + " finished successfully");
iterator.remove();
initNewThread(mapEntry.getValue().getIndex());
startThreads();
System.out.println("Thread №" + mapEntry.getValue().getIndex() + " started");
} else {
if ((System.currentTimeMillis() - mapEntry.getValue().getTimeCreated()) < (THREAD_LIVE_TIME_SEC * 1000)) continue;
int taskIndex = mapEntry.getValue().getIndex();
tasks[taskIndex].stopGeneration(true);
System.out.println("Thread №" + taskIndex + " stoped");
mapEntry.getKey().interrupt();
iterator.remove();
System.out.println("Thread №" + taskIndex + " started");
initNewThread(mapEntry.getValue().getIndex());
startThreads();
}
}
}
threads.clear();
}
public Automat[] getBASE() {
return BASE;
}
}
StackTrace:
Thread №0 started
Thread №1 started
Thread №2 started
Thread №3 started
Thread №4 started
Thread №5 started
Thread №6 started
Thread №7 started
null
null
null
null
null
null
null
null
Exception in thread "main" java.lang.NullPointerException
at ru.stsz.MultiTaskGenerator.getThreadResult(MultiTaskGenerator.java:78)
at ru.stsz.MultiTaskGenerator.<init>(MultiTaskGenerator.java:19)
at ru.stsz.MainApp.main(MainApp.java:6)
Can anyone give me advise how to fix this?
You can Add an assertion each time you need to access your arrays! something like that in the case of emty arrays:
public static void notEmpty(#Nullable Object[] array,String message) {
if (ObjectUtils.isEmpty(array)) {
throw new IllegalArgumentException(message);
}
}
So I have been trying to sort this out for a couple of hours now and I'm sure its something really simple or just a simple mistake i am missing but i have a three class program, control, account and MyThreads.
Im trying to have multipule threads(cards) modify the single account, i'm trying to use a monitor so only one thread can make changes at a time, this is not what i have archived I have somehow just allowed the one thread to access the account class and no others, they seem to just disappear, i assume they are just all on wait but refuse to wake up... any help before i implode?
account code:
class account{
private static int value = 0;
private static int cards = 0;
private static int count = 0;
private static int lock = 0;
public void setValue(int temp){
value = temp;
}
public int getValue(){
// while(lock == 1){
// try{
// wait();
// }catch (InterruptedException e){
// }
// }
return value;
}
synchronized public void withdraw(int temp, String tempID){
while(lock == 1){
try{
wait();
}catch (InterruptedException e){}
}
lock=1;
value= value - temp;
count++;
System.out.println(count + "(" + tempID +")"+" "+temp+" - "+value);
lock = 0;
this.notifyAll();
}
synchronized public void deposit(int temp, String tempID){
while(lock == 1){
try{
wait();
}catch (InterruptedException e){}
}
lock=1;
value= value + temp;
count++;
System.out.println(count + "(" + tempID +")"+" - "+temp+" "+value);
lock = 0;
this.notifyAll();
}
public void setCards(int temp){
cards = temp;
}
public int getCards(){
return cards;
}
public int getCount(){
return count;
}
}
control code:
class control{
public static void main(String [] args){
account acc = new account();
acc.setValue(1000);
acc.setCards(5);
// if(args.length > 0){
// try{
// int tempCards = Integer.parseInt(args[0]);
//
// }catch (NumberFormatException e) {
// System.err.println("Number of Cards : " + args[0] + " must be an integer.");
// System.exit(1);
// }
// try{
// int tempVal = 0;
// tempVal = Integer.parseInt(args[1]);
// acc.setValue(tempVal);
// }catch (NumberFormatException e) {
// System.err.println("Account Value : " + args[1] + " must be an integer.");
// System.exit(1);
// }
// }else{
// System.err.println("No values found, please start program with the number of Cards and Bank Account Value, both in integer format");
// System.exit(1);
// }
System.out.println("Transaction Withdrawal Deposit Balance");
System.out.println(" " + acc.getValue());
for(int i=0; i<=((acc.getCards())-1); i++){
new MyThreads(Integer.toString(i+1));
}
}
}
MyThreads code:
class MyThreads implements Runnable{
private String ID;
private Thread t;
account acc = new account();
MyThreads(String tempID){
ID = tempID;
t = new Thread(this, ID);
t.start();
}
public void run(){
try{
for (int i = 0; i < 20; i++){
if(Math.random()>0.5){
int tempW = 0;
tempW = ((int)(Math.random()*100));
acc.withdraw(tempW, this.ID);
//System.out.println(acc.getCount() + "(" + this.ID +")"+" "+tempW+" -"+acc.getValue());
}else{
int tempD = 0;
tempD = ((int)(Math.random()*100));
acc.deposit(tempD, this.ID);
//System.out.println(acc.getCount() + "(" + this.ID +")"+" "+" - "+tempD+" "+acc.getValue());
}
t.sleep(500);
}
} catch (InterruptedException e) {
System.out.println("Thread " + ID + " interrupted.");
}
System.out.println("Thread " + ID + " exiting.");
}
}
I know its a mess, forgive me im lazy.
Have a look at the definition of a Monitor in Java. In your code, you use the keyword synchronized for two methods, which are the same as:
public void XX(){
lock.lock(); // lock is a private variable
try {
// code here
} finally {
lock.unlock();
}
}
In short, It is a shorthand for explicit locking and will prevent multiple threads to access the methods concurrently.
So, just remove the lock part (i.e. the while(lock==1) block) inside your synchronized methods and it will work. Also, if in other codes you need a real lock, use the Lock class, not an integer.
For more information, there are a lot of good introduction to multithreading on the web, for example this one.
Your question, and thus answer, is a wonderful mixture of static synchronized and wait-notify that's neve being called. Why use static? sounds like a magic word? skip static and make life easier.
Also note that a wait-notify is related to a specific object; if wait-notify are related to different objects they will not communicate. Have a single object that they all synchronize around.
This question already has answers here:
How to set name to the thread?
(6 answers)
Closed 7 years ago.
How to display thread in 100 lines, each line length of 100 characters ?
public class CustomThread extends Thread{
private Thread t;
private String threadName;
CustomThread( String threadName){
this.threadName = threadName;
System.out.println("Creating " + threadName );
}
public void run() {
System.out.println("Running " + threadName );
try {
for(int i = 0; i < 100; i++) {
for (int j = 0; j < 100; j++) {
System.out.println(threadName);
Thread.sleep(50);
}
System.out.println("\n");
}
} catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
System.out.println("Thread " + threadName + " exiting.");
}
public void start ()
{
System.out.println("Starting " + threadName );
if (t == null)
{
t = new Thread (this, threadName);
t.start ();
}
}
}
How to display 100 lines, when each line length of 100 characters.
My main:
public class Main {
public static void main(String[] args) {
CustomThread T1 = new CustomThread("1");
T1.start();
}
}
This character is "1". But how to display 100 lines on 100 characters, that thread ? My code is not work.
Why don't you just name your own thread?
Thread.currentThread().setName("Bob");
System.out.println(Thread.currentThread().getName());
Anyway, to print your rows, change
System.out.println(threadName);
to
System.out.print(threadName);
println() always include a new line character
I have a problem with Threads in Java.
I would like to write a program where there is Class Main which has ArrayList of Threads of some class (Class Task) which just writes a letter and the number. Object Main just wakes one Thread from ArrayList and let it to do something while the same object(Main) sleeps another one.
But there is one problem even if I change the Main.ACTIVE to false it does not end all of the Threads some stay on, and it's random, I just would like to make them end and write:
I am saying goodbay + character - sth like that
public class Main extends Thread {
ArrayList<Thread> threads;
static boolean ACTIVE = true;
public Main() {
super();
threads = new ArrayList<Thread>();
}
public void run(){
Object monitor = new Object();
for (int i = 0; i <= 5; i++) {
threads.add(new Thread(new Task(i + 65, monitor)));
}
long cT = System.currentTimeMillis();
for (int i = 0; i < threads.size(); i++) {
threads.get(i).start();
}
System.out.println("BEFORE synchronized(monitor)");
synchronized(monitor){
while (System.currentTimeMillis() - cT < 1000) {
try{
monitor.notify();
Thread.sleep(50);
monitor.wait();
} catch(Exception e){
e.printStackTrace();}
}
System.out.println("BEFORE ACTIVE= FALSE and after WHILE in Main");
ACTIVE = false;
for(int i = 0; i < threads.size(); i++){
System.out.println(threads.get(i).getState());
}
}
System.out.println("LAST COMMAND IN MAIN");
}
}
public static void main(String[] args) {
new Main().start();
//new Thread(new Task(65)).start();
}
}
And the Task Class
public class Task implements Runnable {
int nr;
char character;
Object monitor;
public Task(int literaASCII, Object monitor) {
this.nr = 0;
this.monitor = monitor;
character = (char) (literaASCII);
}
#Override
public void run() {
synchronized (monitor) {
while (Main.ACTIVE) {
try {
System.out.println("ENTERING WHILE IN TASK");
monitor.wait();
System.out.print(nr + "" + character + ", ");
nr++;
int r = (int) ((Math.random() * 50) + 50); // <500ms,1000ms)
Thread.sleep(r);
} catch (Exception e) {e.printStackTrace();}
monitor.notify();
System.out.println("YYYYYYYYY");
}
System.out.println("AFTER WHILE IN Task");
}
System.out.println("I am saying goodbye " + character);
}
}
I would recommend that you look at the more modern concurrency classes in java.util.concurrent package, especially ExecutorService. And read "Java Concurrency In Practice."
Your problem is for starters that ACTIVE should be marked as volatile. Any variable that is shared by multiple threads needs to somehow be synchronized or marked as volatile so that it will have a memory barrier around its reading and writing.
Another thing you can do from a boolean standpoint is to use the AtomicBoolean class instead of a volatile boolean.
Instead of a static volatile boolean, you might instead consider to have a volatile boolean for each Task object so that Main has more fine grained control over the individual tasks and you are using a static "global" variable. You could even add a task.shutdown() method to set the active flag.
Lastly, as #duffmo mentioned, you should always consider using one of the thread-pools ExecutorService if you always just want to have one thread running. Something like Executors.newFixedThreadPool(1). But I can't quite tell if you only want one thread all of the time. If you used an ExecutorService then main would just do:
ExecutorService threadPool = Executors.newFixedThreadPool(1);
List<Future> futures = new ArrayList<Future>();
for (int i = 0; i <= 5; i++) {
// the monitor would not be needed
threadPool.submit(new Task(i + 65));
}
threadPool.shutdown();
for (Future future : futures) {
// this waits for the working task to finish
future.get();
}
But if you need your background task to stop and start like it is currently doing with the monitor then this model might not work.
Now naswer is
0A, 0B, 0C, 0D, 0E, 0F, 1A, 1B, 1C, 1D, 1E, 1F, WAITING
WAITING
WAITING
WAITING
WAITING
WAITING
LAST COMMAND IN MAIN
I added sleep after starting threads
import java.util.ArrayList;
public class Main extends Thread {
ArrayList<Thread> threads;
volatile static boolean ACTIVE = true;
public Main() {
super();
threads = new ArrayList<Thread>();
}
public void run(){
Object monitor = new Object();
for (int i = 0; i <= 5; i++) {
threads.add(new Thread(new Task(i + 65, monitor)));
}
long cT = System.currentTimeMillis();
for (int i = 0; i < threads.size(); i++) {
threads.get(i).start();
}
try{Thread.sleep(50);}catch(Exception e){e.printStackTrace();}
// System.out.println("BEFORE synchronized(monitor)");
synchronized(monitor){
while (System.currentTimeMillis() - cT < 1000) {
try{
monitor.notify();
Thread.sleep(500);
monitor.wait();}catch(Exception e){e.printStackTrace();}
}
// System.out.println("BEFORE ACTIVE= FALSE and after WHILE in Main");
ACTIVE = false;
for(int i = 0; i < threads.size(); i++){
System.out.println(threads.get(i).getState());
}
}
System.out.println("LAST COMMAND IN MAIN");
}
public static void main(String[] args) {
new Main().start();
//new Thread(new Task(65)).start();
}
}
and the TASK
public class Task implements Runnable {
int nr;
char character;
Object monitor;
public Task(int literaASCII, Object monitor) {
this.nr = 0;
this.monitor = monitor;
character = (char) (literaASCII);
}
#Override
public void run() {
synchronized (monitor) {
while (Main.ACTIVE) {
try {
// System.out.println("ENTERING WHILE IN TASK");
monitor.wait();
System.out.print(nr + "" + character + ", ");
nr++;
int r = (int) ((Math.random() * 50) + 50); // <500ms,1000ms)
Thread.sleep(r);
} catch (Exception e) {e.printStackTrace();}
monitor.notify();
// System.out.println("YYYYYYYYY");
}
System.out.println("AFTER WHILE IN Task");
}
System.out.println("I am saying goodbye " + character);
}
}