I'm writing a testing system and i all i want to do is to count how many seconds had user spent on this question. i.e. i print question(standard System.out.println), then wait 5 seconds and if within these 5 seconds user answered(through standard input), i want to keep this value.
If user hasn't provided an answer in 5 seconds, it must skip this question and continue.
The problem is I'm reading user answers via Scanner object, and something like in.nextInt() is uncontrollable, I suppose.
How can I solve this problem? Here is fragment of my code without that functionality, can you give me some hints what to add?
public void start() {
questions.prepareQuestions(numQuestions);
Scanner in=new Scanner(System.in);
boolean playerIsRight=false,botIsRight=false;
int playerScore=0,botScore=0;
for (int i = 0; i < numQuestions; i++) {
questions.askQuestion(i);
System.out.print("Your answer(number): ");
playerIsRight=questions.checkAnswer(i,in.nextInt()-1); //in.nextInt() contains the answer
botIsRight=botAnswersCorrectly(i + 1);
if(playerIsRight){ playerScore++; System.out.println("Correct!");}
else System.out.println("Incorrect!");
if(botIsRight) botScore++;
System.out.print("\n");
}
if(botScore>playerScore) System.out.println("Machine won! Hail to the almighty transistors!");
else if(playerScore>botScore) System.out.println("Human won! Hail to the power of nature!");
else System.out.println("Tie. No one ever wins. No one finally loses.");
}
I would use two threads in this case. The main thread writes questions, waits for answers, and keeps score. A child thread reads standard input and sends the answers to the main thread, perhaps via a BlockingQueue.
The main thread can wait for five seconds for an answer by using the poll() method on the blocking queue:
…
BlockingQueue<Integer> answers = new SynchronousQueue();
Thread t = new ReaderThread(answers);
t.start();
for (int i = 0; i < numQuestions; ++i) {
questions.askQuestion(i);
System.out.print("Your answer (number): ");
Integer answer = answers.poll(5, TimeUnit.SECONDS);
playerIsRight = (answer != null) && questions.checkAnswer(i, answer - 1);
…
}
t.interrupt();
If this call returns null, the main thread knows that the child thread didn't receive any input during that time, and can update the score appropriately and print the next question.
The ReaderThread would look something like this:
class ReaderThread extends Thread {
private final BlockingQueue<Integer> answers;
ReaderThread(BlockingQueue<Integer> answers) {
this.answers = answers;
}
#Override
public void run() {
Scanner in = new Scanner(System.in);
while (!Thread.interrupted())
answers.add(in.nextInt());
}
}
Used on System.in, the Scanner will block until the user presses Enter, so it might happen that the user has entered some text but not yet pressed Enter when the main thread times out and moves on to the next question. The user would have to delete their pending entry and enter a new answer for the new question. I don't know of a clean way around this awkwardness, since there's not a reliable way to interrupt the nextInt() call.
Related
Now I'm using java to create Timer program.
But the problem is..
I want to add pause option in my program but i cannot find How to add pause option..
So Please give me some advice on how to insert a pause option..
import java.util.Scanner;
public class HelloWorld {
public static void main(String[] args) throws InterruptedException {
Scanner sc = new Scanner(System.in);
System.out.println("Please enter Minutes : ");
int min = sc.nextInt();
long sec = min * 60;
for(long i = sec; i >= 0; i--) {
if(i % 30 == 0) {
System.out.println(i/60 + " min" + i%60 + " sec");
}
Thread.sleep(1000);
}
System.out.println("Timer is over..");
}
}
I'm assuming you want to give the user the option to enter something and cause the countdown to pause. The problem (I think) is that if you ask for input, then that will block the current thread of execution, hence your timer will freeze.
To solve this, you need some form of asynchronous execution. You might want to take a look at Timer: you can use this to schedule a callback to occur every second. This callback function could print the next number in the countdown sequence, while your main thread waits for user input and cancels the timer if the user types pause.
Im trying to create a program whereby users can enter a range of numbers for eg: 1 and then 10, so 1+2+3+4+5+6+7+8+9+10 will be added, but not directly, they can be separated into threads. So user can input the number of threads, for eg: if its 5 threads, thread 1 will perform 1+2, thread 2 performs 3+4 , thread 3 and so on. Each thread will then add together to come up with a total.
I have done the part where the addition works but im not sure how to separate it into the number of user input threads.
You need to somehow keep the index of elements printed to console already, so it could be done by sending a parameter to the run() function which starts from the first element and keeps on to the second thread.
try the following implementation of the code changes:
for (int i=0; i<threadNo; i++)
{
MultithreadingSum object = new
MultithreadingSum(start,end,threadNo,noOfDigits);
object.run(i*(end/threadNo)); //sending a parameter to run()
}
public void run(int time) //time variable to start each time run() is called from current place
{
int total =0;
System.out.println("Thread executed");
for(a = i + time; a <= j/n+time ; a++){
System.out.print(a +" ");
total+=a;
}
System.out.println(getName() + " is "+ total);
}
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I'm designing a print queue program that randomly generates print jobs and, depending on each individual print job's time, "prints" them out for a few seconds, suspending the main thread while another thread continually checks whether the user has pressed the enter key, generating a new print job to be added to the end of the queue in the main thread, or the "Q" button, signalling to end the program. Here is the relevant bit of code:
Scanner input = new Scanner(System.in);
AdPrint addPrint = new AdPrint();
addPrint.start();
for (int i = 0; i < printQueue.size(); i++)
{
System.out.println("Printing " + i + " of " + printQueue.size()
+ "\n" + printQueue.get(i).getJobTime()
+ " seconds remaining."
+ "\nPlease press \"Enter\" to submit a new print"
+ " job or \"Q\" to quit.");
addPrint.setI(i);
addPrint.setInput(input);
addPrint.setJobGen(jobGen);
addPrint.setPrintQueue(printQueue);
Thread.currentThread().sleep(printQueue.get(i).getJobTime() * 1000);
printQueue.add(addPrint.getPrintQueue().get(i));
addPrint.interrupt();
}
AdPrint (which I intentionally misspelled because of another problem I had in eclipse; I changed this class in DropBox on another computer and because there was a new copy, eclipse didn't recognize it as AddPrint for some reason so I had to rename the class to make it work, but that's not the problem here) is the separate thread that handles user input during the waiting period. Before I get into that, I just want to note that I originally had addPrint.start(); in the for loop with no interrupt method, but I realized what would happen is that java would then create infinitely many parallel threads in some sort of runaway feedback loop. I just thought that the values of addPrint (the instance) would just change but that was not the case. Now for AdPrint:
import java.util.LinkedList;
import java.util.Random;
import java.util.Scanner;
public class AdPrint extends Thread
{
private Scanner input;
private Random jobGen;
protected LinkedList<PrintJob> printQueue;
int i;
private boolean run = true;
private String choice = new String();
public void run()
{
while (run)
{
if (input.nextLine() != null)
{
this.choice = input.nextLine();
if (choice.equalsIgnoreCase("q"))
{
for (int i = 0; i < printQueue.size(); i++)
{
System.out.println(printQueue.get(i).toString());
}
}
else if (choice.equalsIgnoreCase("\\n"))
{
int printTime = jobGen.nextInt(10);
PrintJob job = new PrintJob();
job.setJobNum(i);
job.setJobTime(printTime);
printQueue.add(job);
}
}
else if (input.nextLine() == null) {
this.choice = input.nextLine();
}
}
}
Now as it stands, I get the following NullPointerException at if (input.nextLine() != null):
Exception in thread "Thread-0" java.lang.NullPointerException
at AdPrint.run(AdPrint.java:19)
I am new to threads and would like some help here after spending some time tinkering with this. Why am I getting this exception? How do I make this thread, addPrint, check to see if the user has requested another print job?
EDIT:
I forgot to mention that I have getter/setter methods for AdPrint:
public void setInput(Scanner input)
{
this.input = input;
}
In your main() you call start() before you call setInput:
Scanner input = new Scanner(System.in);
AdPrint addPrint = new AdPrint();
addPrint.start();
This means that the Scanner will still be uninitialized and therefore still be null. You must call setInput before you call start(). To test this you can add a print statement right before you call input.nextLine() to see that input is indeed null
I am running some commnads on commmand prompt. I am waiting for the last command's output to complete. I have to read the output and perform the operation. My command's output is very dynamic and I can not predict when I can stop reading.
I am having issues that I dont know when to stop reading. If suppose I keep the while read(), then my last command output is not ending with new line. Is there any mechenism which can tell me if there has been no activity on stdin for last 5mins, then I get some alert??
The approach I took was to create a class implementing Runnable which monitors the value of a shared AtomicInteger flag. This InputRunnable class sleeps for 5 minutes (300000 ms) and then wakes up to check whether the value has been set by the main method. If the user has entered at least one input in the last 5 minutes, then the flag would be set to 1, and InputRunnable will continue execution. If the user has not entered an input in the last 5 minutes, then the thread will call System.exit() which will terminate the entire application.
public class InputRunnable implements Runnable {
private AtomicInteger count;
public InputRunnable(AtomicInteger count) {
this.count = count;
}
public void run() {
do {
try {
Thread.sleep(300000); // sleep for 5 minutes
} catch (InterruptedException e) {
// log error
}
if (count.decrementAndGet() < 0) { // check if user input occurred
System.exit(0); // if not kill application
}
} while(true);
}
}
public class MainThreadClass {
public static void main(String args[]) {
AtomicInteger count = new AtomicInteger(0);
InputRunnable inputRunnable = new InputRunnable(count);
Thread t = new Thread(inputRunnable);
t.start();
while (true) {
System.out.println("Enter a number:");
Scanner in = new Scanner(System.in);
int num = in.nextInt(); // scan for user input
count.set(1);
}
}
}
I tested this code locally and it appears to be working, but please let me know if you have any issues getting it to run on your system.
I had a task to write simple game simulating two players picking up 1-3 matches one after another until the pile is gone. I managed to do it for computer choosing random value of matches but now I'd like to go further and allow humans to play the game. Here's what I already have : http://paste.pocoo.org/show/201761/
Class Player is a computer player, and PlayerMan should be human being. Problem is, that thread of PlayerMan should wait until proper value of matches is given but I cannot make it work this way. Logic is as follows: thread runs until matches equals to zero. If player number is correct at the moment function pickMatches() is called. After decreasing number of matches on table, thread should wait and another thread should be notified. I know I must use wait() and notify() but I can't place them right.
Class Shared keeps the value of current player, and also amount of matches.
public void suspendThread() {
suspended = true;
}
public void resumeThread() {
suspended = false;
}
#Override
public void run(){
int matches=1;
int which = 0;
int tmp=0;
Shared data = this.selectData();
String name = this.returnName();
int number = this.getNumber();
while(data.getMatches() != 0){
while(!suspended){
try{
which = data.getCurrent();
if(number == which){
matches = pickMatches();
tmp = data.getMatches() - matches;
data.setMatches(tmp, number);
if(data.getMatches() == 0){
System.out.println(" "+
name+" takes "+matches+" matches.");
System.out.println("Winner is player: "+name);
stop();
}
System.out.println(" "+
name+" takes "+matches+" matches.");
if(number != 0){
data.setCurrent(0);
}
else{
data.setCurrent(1);
}
}
this.suspendThread();
notifyAll();
wait();
}catch(InterruptedException exc) {}
}
}
}
#Override
synchronized public int pickMatches(){
Scanner scanner = new Scanner(System.in);
int n = 0;
Shared data = this.selectData();
System.out.println("Choose amount of matches (from 1 to 3): ");
if(data.getMatches() == 1){
System.out.println("There's only 1 match left !");
while(n != 1){
n = scanner.nextInt();
}
}
else{
do{
n = scanner.nextInt();
}
while(n <= 1 && n >= 3);
}
return n;
}
}
Well, let me first say that I think you are making this hardier than you need to. If it were me, I would create a 'GameMaster' class whose job it is to loop and tell each player when their turn comes up. Your player classes wouldn't have loops, just a takeTurn method. This way you can remove the waiting/notifying behavior from your player classes.
If you wish to keep the design you have, I would still get rid of the wait/notify and use a Semaphore. Check the docs for proper usage, but the gist is that you would remove the suspend/resume methods and have a acquire() call at the top of your loop and release at the bottom. Just make sure fairness is set to true in the constructor, that way you won't have to worry about a player taking two turns in a row by acquiring the semaphore lock twice in a row.
Ok, so I managed to do it without wait() etc.
http://paste.pocoo.org/show/201966/
When you find yourself having to set up communication between threads to synchronize their execution, just so that a specified sequence of events takes place (such as taking turns playing a game), it's a good sign that you may have more threads than you need.
In this case, consider a single thread that executes a takeTurn() method on various extensions of a Player class might make life easier for you. You could make Player an abstract base class that mandates .takeTurn(), then have HumanPlayer and MachinePlayer classes encapsulate the code that makes sense for each type of player inside that method. This should make extension to larger numbers of players relatively trivial as compared to lots of wait() and notify().