I have a piece of practice code that is supposed to accept 1010 as the code when a user enters the code on the keyboard. The thread that keeps checking if the code was entered right wont run unless i put a Thread.sleep(1); in the run()
I wanted to know whats the reason behind this.
Class1:
import java.util.Scanner;
public class Class1 {
private static boolean valid = true, accepted = false, exit = false;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
newThread t1 = new newThread();
t1.start();
do {
try {
int code = Integer.parseInt(input.nextLine());
if(code == 1010)
accepted = true;
else
System.out.println("Please try again!");
}catch(Exception e) {
System.out.println("Please try again!");
}
}while(!exit);
}
public static boolean getValid() {
return valid;
}
public static void setValid(boolean input) {
valid = input;
}
public static boolean getAccepted() {
return accepted;
}
public static void setAccepted(boolean input) {
accepted = input;
}
}
newThread:
public class newThread extends Thread{
public void run() {
do {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(Class1.getAccepted())
Class1.setValid(false);
}while(Class1.getValid());
System.out.println("Code accepted");
}
}
Expected without Thread.sleep(1);:
1010
Code accepted
Actual results:
1010
Without sleep the newThread consumes all cpu and has no natural break point. In the
Java Language Specification you can read more about it.
Related
I am trying to create a loading sequence of 3 dots that repeats itself until input from the user breaks the loading sequence specifically the enter key. i connot for the life of me get the infinite while loop to end with input
public class loop {
public static void AnyKey() {
try {
System.in.read();
loading(false);
} catch (Exception e){}
}
public static void pause(long duration) {
try{
Thread.sleep(duration);
} catch (InterruptedException e){}
}
public static void loading(boolean status){
if (status == true) {
while (status) {
pause(500);
int i;
for (i = 0; i <3; i++){
System.out.print(".");
pause(500);
}
System.out.print("\b\b\b");
}
}
}
public static void main(String[] args) {
loading(true);
AnyKey();
}
}
In your current code, the main method calls loading and never leaves the function. If you go through loading(true) step by step, you find that since while(status) is always true you are stuck there and AnyKey() is never called.
Also, System.in.read(); is a blocking call. This means that you will wait for user input but will be unable to print the '...'. Instead I recommend your read the documentation for input stream, there you will find the .read() function but also the .available() function which will let you know if any characters have been entered in the input buffer.
Those should be all the tools you need to figure this one out (I think).
Hope this helps!
I figured it out i needed to learn about and use Threads and global variables check out my code below im fairly pleased with myself i was working on this for 3 days now lol
import java.util.Scanner;
class AnyKey extends Thread {
public void run() {
Scanner scanner = new Scanner(System.in);
scanner.nextLine();
loadingDots.loadingStatus = false;
}
}
public class loadingDots {
public static boolean loadingStatus;
public static void pause(long duration) {
try {
Thread.sleep(duration);
} catch (InterruptedException e) {}
}
public static void loading(){
loadingStatus = true;
while (loadingStatus) {
pause(500);
int i;
for (i = 0; i < 3; i++) {
if (!loadingStatus){
break;
}
System.out.print(".");
pause(500);
}
System.out.print("\b\b\b");
}
}
public static void main(String[] args) {
AnyKey anykey = new AnyKey();
anykey.start();
loading();
}
}
I am making a 3 thread communication. User will input the message for the thread to communicate. The threads suppose to communicate until one of the thread says "Bye". But in my program thread 1 execute only once then gone and the other two threads continue communicate.
The Output of my program looks like this.
Here is the code:
import java.util.Scanner;
public class Conversation {
public static void main(String[] args) {
Chat chat = new Chat();
new Thread1(chat).start();
new Thread2(chat).start();
new Thread3(chat).start();
}
}
class Chat {
Scanner sc1 = new Scanner(System.in);
Scanner sc2 = new Scanner(System.in);
Scanner sc3 = new Scanner(System.in);
String str1,str2,str3;
int flag = 0;
public synchronized void getTalk1() throws InterruptedException {
if (flag==1 ) {
wait();
}
System.out.print("User1: ");
str1 = sc1.nextLine();
if(str1.equalsIgnoreCase("bye")) {
System.out.println("\nUser1 has left the chat. Conversation ended.");
System.exit(0);
}
flag = 1;
notifyAll();
}
public synchronized void getTalk2() throws InterruptedException {
if (flag == 0) {
wait();
}
System.out.print("User2: ");
str2 = sc2.nextLine();
if(str2.equalsIgnoreCase("bye")) {
System.out.println("\nUser2 has left the chat. Conversation ended.");
System.exit(0);
}
flag = 0;
notifyAll();
}
public synchronized void getTalk3() throws InterruptedException {
if (flag == 3) {
wait();
}
System.out.print("User3: ");
str3 = sc3.nextLine();
if(str3.equalsIgnoreCase("bye")) {
System.out.println("\nUser3 has left the chat. Conversation ended.");
System.exit(0);
}
flag = 3;
notifyAll();
}
}
class Thread1 extends Thread {
Chat chat;
public Thread1(Chat chat) {
this.chat = chat;
}
public void run() {
try {
while(true) {
chat.getTalk1();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Thread2 extends Thread {
Chat chat;
public Thread2(Chat chat) {
this.chat = chat;
}
public void run() {
try {
while(true) {
chat.getTalk2();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Thread3 extends Thread {
Chat chat;
public Thread3(Chat chat) {
this.chat = chat;
}
public void run() {
try {
while(true) {
chat.getTalk3();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
You don't necessarily need to create 3 separate Thread classes for 3 users. You also don't need 3 separate methods for each user. It's hard to read, maintain, and debug.
I wrote a very simple program for you. In your application, synchronised is used to wrap the whole method. It's hard to read, and it's unclear why you synchronised the entire method body. In my example, there is a single point where synchronisation is required and it's well defined: when a user wants to say something to the chat.
Have a look.
class Application {
public static void main(String[] args) {
final Chat chat = new Chat();
chat.registerUser(new User("user1", chat));
chat.registerUser(new User("user2", chat));
chat.registerUser(new User("user3", chat));
}
}
class Chat {
private final Scanner scanner = new Scanner(System.in);
private final List<User> users = new ArrayList<>();
private void registerUser(User user) {
users.add(user);
System.out.format("'%s' connected to the chat.\n", user);
user.start();
}
public void sendMessage(User user) {
final String reply = scanner.nextLine();
System.out.format("%s: %s\n", user, reply);
if (reply.equalsIgnoreCase("bye")) {
users.forEach(Thread::interrupt);
System.out.println("The chat is over.");
} else {
notifyAll();
}
}
}
class User extends Thread {
private final String id;
private final Chat chat;
public User(String id, Chat chat) {
this.id = id;
this.chat = chat;
}
public void run() {
while (true) {
try {
synchronized (chat) {
chat.sendMessage(this);
chat.wait();
}
} catch (InterruptedException e) {
throw new IllegalArgumentException("Someone left. I am done as well.");
}
}
}
#Override
public String toString() {
return id;
}
}
An example would be
'user1' connected to the chat.
'user2' connected to the chat.
'user3' connected to the chat.
hi
user1: hi
hello
user3: hello
what's up?
user2: what's up?
nothing
user3: nothing
what?
user1: what?
bye
user2: bye
The chat is over.
To read:
the producer–consumer problem
You have 3 synchronized methods but each method is used by 1 thread only.
You have misunderstood the role of synchronized.
synchronized means an object having synchronized block does not let two threads to access the code inside the block at the same time.
Therefore, the 3 threads access one shared resource (System.in) without synchronization and the behaviour is undefined.
Hope this code helps.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Chat chat = new Chat();
new T1(chat).start();
new T2(chat).start();
new T3(chat).start();
}
}
class Chat {
Scanner sc1 = new Scanner(System.in);
Scanner sc2 = new Scanner(System.in);
Scanner sc3 = new Scanner(System.in);
String str1,str2,str3;
int flag = 1;
public synchronized void Person1() throws InterruptedException {
while(flag==2 || flag==3) {
wait();
}
System.out.print("Person 1: ");
str1 = sc1.nextLine();
if(str1.equalsIgnoreCase("bye")) {
System.out.println("\nPerson 1 has left the chat. Conversation ended.");
System.exit(0);
}
flag = 2;
notifyAll();
}
public synchronized void Person2() throws InterruptedException {
while(flag==1 || flag==3) {
wait();
}
System.out.print("Person 2: ");
str2 = sc2.nextLine();
if(str2.equalsIgnoreCase("bye")) {
System.out.println("\nPerson 2 has left the chat. Conversation ended.");
System.exit(0);
}
flag = 3;
notifyAll();
}
public synchronized void Person3() throws InterruptedException {
while(flag==1 || flag==2) {
wait();
}
System.out.print("Person 3: ");
str3 = sc3.nextLine();
if(str3.equalsIgnoreCase("bye")) {
System.out.println("\nPerson 3 has left the chat. Conversation ended.");
System.exit(0);
}
flag = 1;
notifyAll();
}
}
class T1 extends Thread {
Chat chat;
public T1(Chat chat) {
this.chat = chat;
}
public void run() {
try {
while(true) {
chat.Person1();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class T2 extends Thread {
Chat chat;
public T2(Chat chat) {
this.chat = chat;
}
public void run() {
try {
while(true) {
chat.Person2();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class T3 extends Thread {
Chat chat;
public T3(Chat chat) {
this.chat = chat;
}
public void run() {
try {
while(true) {
chat.Person3();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
I'm currently practicing Threads so I tasked myself to write a program that will create 2 threads. The first one will endlessly print a character and the second one will endlessly wait for input and then pass it to the first Thread. Then Thread #1 should print the passed character. Here's what I wrote:
public class A extends Thread {
public char dif;
Scanner stdin = new Scanner(System.in);
#Override
public void run() {
for (; ; ) {
dif = stdin.nextLine().charAt(0);
MyThread.setCh(dif);
}
}
}
This thread takes input and then passes it to this one:
public class MyThread extends Thread {
public static char ch;
public static void setCh(char cha) {
ch = cha;
}
public static char getCh() {
return ch;
}
#Override
public void run() {
for(;;) {
try {
Thread.sleep(300);
}
catch(InterruptedException e) {
e.printStackTrace();
}
System.out.print(getCh());
}
}
}
And what happens in the main():
MyThread endless = new MyThread();
MyThread.setCh('$');
A set = new A();
endless.start();
set.start();
However, this doesn't work as intended. No matter what I type, the program keeps printing $. Also for some reason the first time I type a character I get an Out of bounds exception.
Probably, the easiest way to approach this, is to use BlockingQueue.
Effectively, in your example the thread, that receives character from System.in is producer and the thread that prints received character is consumer.
So, here is the code that achieves your goal:
import java.util.*;
import java.util.concurrent.*;
class Setup {
public static void main(String[] args) {
BlockingQueue<Character> q = new LinkedBlockingQueue<>();
Producer p = new Producer(q);
Consumer c = new Consumer(q);
new Thread(p).start();
new Thread(c).start();
}
}
class Producer implements Runnable {
private final BlockingQueue<Character> queue;
private final Scanner scanner = new Scanner(System.in);
Producer(BlockingQueue<Character> q) { queue = q; }
public void run() {
try {
while (true) {
queue.put(produce());
}
} catch (InterruptedException ex) {
Thread.currentThread().interrupt(); // set interrupt flag
} finally {
scanner.close();
}
}
Character produce() {
return scanner.nextLine().charAt(0);
}
}
class Consumer implements Runnable {
private final BlockingQueue<Character> queue;
Consumer(BlockingQueue<Character> q) { queue = q; }
public void run() {
try {
while (true) {
consume(queue.take());
}
} catch (InterruptedException ex) {}
}
void consume(Character c) {
System.out.println("Received character: " + c);
}
}
The problem actually you have it is quite small delay in Thread.sleep(300);
Try to set sleep for a few seconds Thread.sleep(5000);. You have to type something before it will print previous char
I would like to block a Card in my abstract ATM.
At this manner, I need to interrupt the program if the PIN wasn't accepted after the third attempt so that the Main class won't execute the next Methods.
Is it System.exit(0) the optimal decision? I chose this one because it's simple, but I'm not sure.
public boolean authenticity(int tries) {
if (tries <= 3)
{
short pin = sc.nextShort();
if (pin == 1234) {
System.out.println("PIN is correct");
System.out.println("Card is active for operation!");
return true;
} else {
System.out.println("PIN isn't correct! You used " + tries +" attempt!");
return authenticity(++tries);
}
}
System.out.println("\nCard was blocked!");
System.exit(0);
return false;
}
class Main looks so:
public class Main {
private static Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
ATM atm = new ATM();
MasterCard aeroflotCard = new MasterCard();
atm.initCard(aeroflotCard);
aeroflotCard.authenticity(1); // if pin is wrong, than you are looser:)
System.out.println("\nRefill your balance:");
aeroflotCard.add(sc.nextInt());
aeroflotCard.balance();
}
You may try the following piece of code:
public boolean authenticity(int tries) throws yourException {
if (tries <= 3) {
// ...
} else {
throw new yourException("\nCard was blocked!");
}
}
In the main method:
public static void main(String[] args) {
try {
aeroflotCard.authenticity(1);
System.out.println("\nRefill your balance:");
aeroflotCard.add(sc.nextInt());
aeroflotCard.balance();
} catch (yourException e) {
System.err.println(e.getMessage());
}
}
In the yourException class:
public class yourException extends Exception {
// here you can override needed methods
}
I have two very similar programs each trying to run two threads OddThread and EvenThread and trying to print the odd and even numbers in sequence . While the first one works , the second one hangs . Can anyone please pinpoint the bug in the second program ?
The first one which works :
public class ThreadTest {
public static void main(String[] args) {
System.out.println("Odd Even test");
NumHolder objNumHolder = new NumHolder();
Odd o1 = new Odd(objNumHolder, "Odd Number Thread");
Even e1 = new Even(objNumHolder, "Even Number Thread");
o1.start();
e1.start();
}
}
class NumHolder {
private int intCurrNum;
private boolean isEven = false;
public synchronized void printOddNumber(String tname) {
while (isEven == true){
try {
wait();
}catch (InterruptedException e) {
}
}
isEven = true;
System.out.println("Thread Name="+tname + "===Number="+intCurrNum);
intCurrNum += 1;
notifyAll();
}
public synchronized void printEvenNumber(String tname) {
while (isEven == false) {
try {
wait();
} catch (InterruptedException e) {
}
}
isEven = false;
System.out.println("Thread Name="+tname + "===Number="+intCurrNum);
intCurrNum += 1;
notifyAll();
}
}
class Even extends Thread {
private NumHolder objNumHolder;
public Even(NumHolder p_objNumHolder, String name) {
super(name);
objNumHolder=p_objNumHolder;
}
public void run() {
for (int i = 0; i < 10; i++) {
objNumHolder.printEvenNumber(getName());
}
}
}
class Odd extends Thread {
private NumHolder objNumHolder;
public Odd(NumHolder p_objNumHolder,String name) {
super(name);
objNumHolder = p_objNumHolder;
}
public void run() {
for (int i = 0; i < 10; i++) {
objNumHolder.printOddNumber(getName());
}
}
}
The second code which hangs :
class PrintClass {
int intCurrNum;
private boolean isEven = false;
synchronized void printOdd(){
while(isEven){
try{
wait();
}catch(InterruptedException ie){
System.out.println("Interrupted exception in printOdd()");
ie.printStackTrace();
}
isEven = true;
System.out.println("Thread Name="+Thread.currentThread().getName() + "===Number="+intCurrNum);
intCurrNum += 1;
notifyAll();
}
}
synchronized void printEven(){
while(!isEven){
try{
wait();
}catch(InterruptedException ie){
System.out.println("Interrupted exception in printEven()");
ie.printStackTrace();
}
isEven = false;
System.out.println("Thread Name="+Thread.currentThread().getName() + "===Number="+intCurrNum);
intCurrNum += 1;
notifyAll();
}
}
}
class ThreadOdd extends Thread {
PrintClass pc = null;
ThreadOdd(PrintClass pc , String name){
super(name);
this.pc = pc;
}
public void run(){
for (int i = 0; i < 10; i++) {
pc.printOdd();
}
}
}
class ThreadEven extends Thread {
PrintClass pc = null;
ThreadEven(PrintClass pc,String name){
super(name);
this.pc = pc;
}
public void run(){
for (int i = 0; i < 10; i++) {
pc.printEven();
}
}
}
public class EvenOddPrintClass {
public static void main(String[] args){
PrintClass pc = new PrintClass();
Thread to = new ThreadOdd(pc,"ThreadOdd");
Thread te = new ThreadEven(pc,"ThreadEven");
to.start();
te.start();
}
}
Thanks.
I suggest you run your code in the debugger and step through both threads. It's very educational. You will see exactly where the error is.
In both versions, isEven starts out as false.
In the first version, printOddNumber will skip the whole while loop, print the odd number, set isEven to true and notify the even thread, which will print the even number and notify the odd thread again etc. in sequence.
In the second version, printOddNumber will skip the whole while loop, including printing the number and notifying the even thread. After 10 attempts it will exit without having printed anything, and leaving the even thread hanging without ever having notified it.
Interesting. So initially the isEven = false. If the printOdd() is called first then the while (isEven) test is false so printOdd() will exit immediately without generating any output. The while loops in your first program only encompass the wait test, not the entire method.
Then when printEven() is called by the other thread, it will call wait() and hang since there is no other thread to call notifyAll().
You only should want the while loop around the wait since you are going to exit after you print out the even or odd number anyway, right? So the logic in the first program is correct.
public class CountDownApp
{
public static void main(String[] args)
{
Thread count1 = new CountDownEven();
Thread count2 = new CountDownOdd();
count1.start();
count2.start();
}
}
class CountDownEven extends Thread
{
public void run()
{
for(int i=10;i>0;i-=2)
{
System.out.print(+i+"-");
try {
Thread.sleep(2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class CountDownOdd extends Thread
{
public void run()
{
for(int i=9;i>0;i-=2)
{
System.out.print(+i+"-");
try {
Thread.sleep(2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}