My result
Expected result
public void run () {
try {
handlers.addElement (this);
broadcast("Welcome " + name);
while(handlers.size() != 2){
if(handlers.size() > 2){
this.out.writeUTF ("The Room is full!");
this.out.flush();
handlers.removeElement(this);
socket.close();
}
}
broadcast("No of Player: " + handlers.size());
for(int i = 0; i < handlers.size(); i++){
GameHandler player = (GameHandler) handlers.get(i);
broadcast("Player " + (i + 1) + ": " + player.name);
}
System.out.println("Game starts!");
startGame(4);
....
}
protected static void broadcast (String message) {
synchronized (handlers) {
Enumeration e = handlers.elements ();
while (e.hasMoreElements ()) {
GameHandler handler = (GameHandler) e.nextElement ();
try {
handler.out.writeUTF (message);
handler.out.flush ();
} catch (IOException ex) {
handler.stop ();
}
}
}
}
The problem is the difference between the expected result and my actual result. I have no idea why the broadcast before the while loop runs normally but others run twice
Your problem is that in your case, each of the thread is sending the broadcast. Either you need to have a "master" / "server" of games thread that does the "system announcements" broadcasting, -or- elect one of the client threads (maybe the "player 1" thread?) to send the announcements.
The problem is the difference between the expected result and my actual result. I have no idea why the broadcast before the while loop runs normally but others run twice
You really don't give enough details on your problem but I see these issues:
You talk about TCP and the code mentions sockets but you are processing a local elements collection. Unless you are talking to the same JVM over TCP (which is strange) the elements collection is going to start 2 players on each client. Is that really what you expect?
Even though you says elements is a Vector you still need to synchronize on it at the start of the run() method because you are performing multiple operations on it and there are race conditions. For example, if 3 handlers are added, they will all remove themselves and close their own sockets.
Vector really is an outdated collection. You should be using something else.
When the first thread adds itself to elements it then enters a spin loop waiting for the second person to join the game. Seems like a waste there. Some small Thread.sleep(...) would be appropriate.
If the room is full I suspect that the thread should return; from the run() method. Instead it continues on which I suspect is not good.
Hope something here helps.
Related
In Java/Android, is there a way to check whether the currently executing line of code is executing on a background thread or not?
I have a lil' program I'm conjuring up that has finally reached the full-spaghetti stage... this was intentional, you see, because this way... if a competitor gets their hands on the code, and they "open the hood," after looking at it for more than 20 seconds, their hair will catch on fire and they'll run away screaming... but now even I am getting confused and I need to check for this condition somehow.
Exhibit-A:
// can be called from 1,067 places... some of which are background threads.
public void startDoingAFunDance(String caller, int wobbleIntensity, int spineAngle, int feetSeparationInInches) {
if (!validCallersForFunDance.contains(caller)) {
Log.i("XXX", "Caller not allowed.");
return;
}
boolean wasCalledFromBackgroundThread = // ? < what to put here > ?
Log.i("XXX", "Was startDoingAFunDance() called from a background thread? And the answer is: " + wasCalledFromBackgroundThread);
// classified
}
An easy way to know it might be the following
boolean wasCalledFromBackgroundThread = (Thread.currentThread().getId() != 1);
background threads doesn't have id 1 (UI thread has).
everyone!
I have just created a brute force bot which uses WebDriver and multithreading to brute force a 4-digit code. 4-digit means a range of 0000 - 9999 possible String values. In my case, after clicking the "submit" button, not less than 7 seconds passes before the client gets a response from the server. So, I have decided to use Thread.sleep(7200) to let the page with a response be fully loaded. Then, I found out that I couldn't afford to wait for 9999*7,5 seconds for the task to be accomplished, so I had to use multithreading. I have a Quad-Core AMD machine with 1 virtual core per 1 hardware one, which gives me the opportunity to run 8 threads simultaneously. Ok, I have separated the whole job of 9999 combinations between 8 threads equally, each had got a scope of work of 1249 combinations + remainder thread starting at the very end. Ok, now I'm getting my job done in 1,5 hours (because the right code appears to be in the middle of the scope of work). That is much better, BUT it could be even more better! You know, the Thread.sleep(7500) is a pure waste of time. My machine could be switching to other threads which are wait() because of limited amount of hardware cores. How to do this? Any ideas?
Below are two classes to represent my architecture approach:
public class BruteforceBot extends Thread {
// All the necessary implementation, blah-blah
public void run() {
brutforce();
}
private void brutforce() {
initDriver();
int counter = start;
while (counter <= finish) {
try {
webDriver.get(gatewayURL);
webDriver.findElement(By.name("code")).sendKeys(codes.get(counter));
webDriver.findElement(By.name("code")).submit();
Thread.sleep(7200);
String textFound = "";
try {
do {
textFound = Jsoup.parse(webDriver.getPageSource()).text();
//we need to be sure that the page is fully loaded
} while (textFound.contains("XXXXXXXXXXXXX"));
} catch (org.openqa.selenium.JavascriptException je) {
System.err.println("JavascriptException: TypeError: "
+ "document.documentElement is null");
continue;
}
// Test if the page returns XXXXXXXXXXXXX below
if (textFound.contains("XXXXXXXXXXXXXXXx") && !textFound.contains("YYYYYYY")) {
System.out.println("Not " + codes.get(counter));
counter++;
// Test if the page contains "YYYYYYY" string below
} else if (textFound.contains("YYYYYYY")) {
System.out.println("Correct Code is " + codes.get(counter));
botLogger.writeTheLogToFile("We have found it: " + textFound
+ " ... at the code of " + codes.get(counter));
break;
// Test if any other case of response below
} else {
System.out.println("WTF?");
botLogger.writeTheLogToFile("Strange response for code "
+ codes.get(counter));
continue;
}
} catch (InterruptedException intrrEx) {
System.err.println("Interrupted exception: ");
intrrEx.printStackTrace();
}
}
destroyDriver();
} // end of bruteforce() method
And
public class ThreadMaster {
// All the necessary implementation, blah-blah
public ThreadMaster(int amountOfThreadsArgument,
ArrayList<String> customCodes) {
this();
this.codes = customCodes;
this.amountOfThreads = amountOfThreadsArgument;
this.lastCodeIndex = codes.size() - 1;
this.remainderThread = codes.size() % amountOfThreads;
this.scopeOfWorkForASingleThread
= codes.size()/amountOfThreads;
}
public static void runThreads() {
do {
bots = new BruteforceBot[amountOfThreads];
System.out.println("Bots array is populated");
} while (bots.length != amountOfThreads);
for (int j = 0; j <= amountOfThreads - 1;) {
int finish = start + scopeOfWorkForASingleThread;
try {
bots[j] = new BruteforceBot(start, finish, codes);
} catch (Exception e) {
System.err.println("Putting a bot into a theads array failed");
continue;
}
bots[j].start();
start = finish;
j++;
}
try {
for (int j = 0; j <= amountOfThreads - 1; j++) {
bots[j].join();
}
} catch (InterruptedException ie) {
System.err.println("InterruptedException has occured "
+ "while a Bot was joining a thread ...");
ie.printStackTrace();
}
// if there are any codes that are still remain to be tested -
// this last bot/thread will take care of them
if (remainderThread != 0) {
try {
int remainderStart = lastCodeIndex - remainderThread;
int remainderFinish = lastCodeIndex;
BruteforceBot remainderBot
= new BruteforceBot(remainderStart, remainderFinish, codes);
remainderBot.start();
remainderBot.join();
} catch (InterruptedException ie) {
System.err.println("The remainder Bot has failed to "
+ "create or start or join a thread ...");
}
}
}
I need your advise on how to improve the architecture of this app to make it successfully run with say, 20 threads instead of 8. My problem is - when I simply remove Thread.sleep(7200) and at the same time order to run 20 Thread instances instead of 8, the thread constantly fails to get a response from the server because it doesn't wait for 7 seconds for it to come. Therefore, the performance becomes not just less, it == 0; Which approach would you choose in this case?
P.S.: I order the amount of threads from the main() method:
public static void main(String[] args)
throws InterruptedException, org.openqa.selenium.SessionNotCreatedException {
System.setProperty("webdriver.gecko.driver", "lib/geckodriver.exe");
ThreadMaster tm = new ThreadMaster(8, new CodesGenerator().getListOfCodesFourDigits());
tm.runThreads();
Okay, so everyone can't wait until my question will get a response so I decided to answer it as soon as I can (now!).
If you would like to increase a performance of a Selenium WebDriver-based brute force bot like this one, you need to reject using the Selenium WebDriver. Because the WebDriver is a separate process in the OS, it does not even need a JVM to run. So, every single instance of the Bot was not only a thread managed by my JVM, but a Windows process also! This was the reason why I could hardly use my PC when this app was running with more than 8 threads (each thread was invoking a Windows process geckodriver.exe or chromedriver.exe). Okay, so what you really need to do to increase performance of such a brute force bot is to use HtmlUnit instead of Selenium! HtmlUnit is a pure Java framework, its jar could be found at Maven Central, its dependency could be added to your pom.xml. This way, brute forcing a 4-digit code takes 15 - 20 minutes, taking into account that after each attempt the website responds not faster than 7 seconds after each attempt. To compare, with Selenium WebDriver it took 90 minutes to accomplish the task.
And thanks again to #MartinJames, who has pointed that Thread.sleep() does let the hardware core to switch to other threads!
I want to use Thread.sleep() in my java application. But does not work. Program works after removing sleep.
In my program I am running multiple threads and want that each move forward at a variable speed. Some may get executed more some less. So I am using sleep in each with a random number as argument.
If there another way to do this. Without using sleep.
Here is the part where I am using the sleep function.
public void run()
{
Random r = new Random();
int t;
while(true)
{
if(total == 1)
{
// win();
break;
}
if(doa == 1)
break;
// Player x = e[r.nextInt(20)%2];
Player x = choose();
x.attack(this, 10 + (power==1?5:0));
if(r.nextInt(100)%(5 - (power==2?2:0)) == 0)
System.out.println(" " + name + " used Potion effect (" + potionno++ + ") .. now " + name + "'s Health is " + (h+= 10 + r.nextInt(20)));
try
{
sleep(50 + r.nextInt(1000));
}
catch(InterruptedException c)
{ ; }
}
if(doa == 1)) {
// and so on
.
.
and here is my doGet function used for initiation
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String s;
s = request.getParameter("name");
try{
Player.out = out;
Player.e[0] = new Player("Kartik",2);
Player.e[1] = new Player(s,1);
Player.e[2] = new Player("Anirudh",3);
Player.e[3] = new Player("Vinita");
Player.e[4] = new Player("Shivank");
for(Player p: Player. e)
p.start();
}
catch(Exception e)
{
out.print("WRONG");
}
}
You shouldn't do that since, in general, Java EE/servlet containers work on the assumption their applications do not spawn threads (or modify the execution or configuration of existing ones, which you are doing with Thread.sleep()) of their own all nilly willy.
It is possible, but generally frowned upon unless you know what you are doing. See this answer that succinctly but excellently explains why: https://stackoverflow.com/a/533847/201722
As of why your call to Thread.sleep() doesn't work, it is because your servlet container is multi-threaded. Your call to Thread.sleep() is simply putting the thread that is handling your current HTTP request to sleep. But the container is still alive and kicking. If you send another HTTP request, it will grab another thread distinct from the one you put to sleep to handle it.
So, from your POV, it looks like it is not working. But it is working, you put the poor thread to sleep, and the container goes ok, here is another one for you. It just so happens you don't know what the heck is going on.
I would suggest you take the time to go through both the Java and the Java EE tutorials made available by Oracle (former Sun.) Google it and you will find it.
== EDIT ==
I would also recommend the OP to read the following succinct explanation against indiscriminately meddling with threads in a container.
http://www.psionicwave.com/blog/2012/12/15/threading-in-web-containers/
Many things are wrong with your current approach, I'll try to point out some.
Your Player apparently extends Thread. That's an antipattern; you should only implements Runnable and pass the instance of your class to new Thread();
the basic flavor of a Servlet-based Web application is based on a strict request-response paradigm, where the respone happens as soon as possible. What you (possibly) are looking for is a "long response", asynchronous style. This can be achieved with new features in Servlet 3.0, but is well beyond the scope of this answer;
assuming for a moment that you just want a go at it, a quick patch is to append
for (Player p : Player.e) p.join();
to your existing doGet method. This will postpone the returning of doGet until all your subthreads die. You will also need to routinely flush the writer to force the immediate sending of the data to the client side (or use PrintWriter#println, which has auto-flush semantics).
I need to check how many events are detected within 2 seconds. I have the timer working and I have everything else working...but I ran into a problem: the loop only checks one time, per second and I can't seem to figure out how to fix that. I need it to check constantly during these two seconds to see how many events there were in total!
Here is what I have:
int seconds = 0;
System.out.println("Seconds: " + seconds);
while(seconds < 2)
{
//Wait 1 second
try {
Thread.sleep(1000);
}
catch(Exception e) {}
seconds++;
System.out.println("Seconds: " + seconds);
//This needs to be looping the whole time.
//But right now, it's being blocked and only checked once
if(eventDetected() && seconds <= 2){
events++;
}
}
So you can see my problem. I can't split them up because then the second timer would run, and THEN eventDetected() would be checked. I need it to check constantly DURING the two second timer...so I basically need both things to happen at once. Is there any way I can do this?
Thanks for any help ahead of time!
I think your design pattern needs work -- I don't know what type event you're looking to detect, but no matter how short your sleep time is, there's a chance you could miss an event using the current pattern. Here's what I suggest:
Have eventDetected() increment your events counter. That way, you won't miss an event.
Then, you just need a way to turn on and off listening (and perhaps resetting the event counter). If you're sure that in you're current pattern you are really in a different thread that won't block your eventDetected() method, you could set a flag to check. For example:
When you want to start listening:
listenForEvents = true;
In eventDetected():
if (listenForEvents) { events++; }
When you want to stop listening (for example, after your Thread.sleep() call):
listenForEvents = false;
With multithreading, make sure to watch out for concurrency issues checking and setting the variables, of course.
I would tell you what kind of event I have to keep track of but then I'd have to kill you :D
Answered my own question. Hopefully this will help anyone else out who has a similar problem at some point! I looked up multithreading a bit...
I created a new class EventTimer which implements Runnable, with a public field for seconds:
public class EventTimer implements Runnable{
int seconds;
static int timerThreadCount = 0;
Thread t;
public EventTimer() {
timerThreadCount++;
this.seconds = 0;
t = new Thread(this, "Event Timer");
t.start(); // Start the thread
}
#Override
public void run() {
// TODO Auto-generated method stub
while(seconds < 2)
{
//Wait 1 second
try {
Thread.sleep(1000);
}
catch(Exception e) {
System.out.println("Waiting interupted.");
}
seconds++;
System.out.println("Seconds: " + seconds);
}
}
}
Then I used an instance of the EventTimer, and used a while loop & if statement to solve my problem.
EventTimer t = new EventTimer();
while(t.seconds < 2){
if(eventDetected()) events++;
}
It was actually quite simple! I realize that each iteration of my loop of operation (since the entire code piece above is inside an infinite loop) will create a new EventTimer thread and I will eventually run into memory problems however. How would I close/end a thread after the timer has reached 2 seconds?
I have the following code that runs whenever you click the Start button on my program. I have denoted via comments where I want the timer to go, problem is, when I do thread.sleep(time) it freezes my program! So, I was wondering if someoen could just simply add atimer to my code so it runs the first bit, waits, then runs it again based on bumpNum.
Code:
public class startReplyButtonListener implements ActionListener{
public void actionPerformed(ActionEvent ev){
int length = textAreaReplyMessage.getText().length();
int remLen = 400 - length;
String strHTML = neo.get("http://www.neopets.com/neoboards/topic.phtml?topic=" + txtTopicID.getText());
/*strHTML = neo.post("/neoboards/process_topic.phtml?", new String[][] {{"boardType", "topic_id", "board_id", "message", "next", "remLen"}, {"reply", txtTopicID.getText(), "4", textAreaReplyMessage.getText() , "1", ((Integer)remLen).toString()}});
if(strHTML.contains("No topic with ID")){
txtLog.append("Invalid Topic ID! \n");
}
else{
txtLog.append("Bumped Topic ID " + txtTopicID.getText() + "\n");
}
*/
System.out.println(strHTML);
bumpNum = 5;
wait = Integer.parseInt(textWait1.getText()) * 1000; //converting to miliseconds
int i=1;
do{
strHTML = neo.post("/neoboards/process_topic.phtml?", new String[][] {{"boardType", "topic_id", "board_id", "message", "next", "remLen"}, {"reply", txtTopicID.getText(), "4", textAreaReplyMessage.getText() , "1", ((Integer)remLen).toString()}});
txtLog.append("Board Bumped. Waiting "+ ((Integer)(wait/1000)).toString() +" Seconds..." + "\n");
//ADD TIMER HERE
i++;
}while(i <= bumpNum);
}
}
What I wish to accomplish:
User indicates how many times they want to "post"(indicated by bumpNum), the loop will first, post once:
strHTML = neo.post("/neoboards/process_topic.phtml?", new String[][] {{"boardType", "topic_id", "board_id", "message", "next", "remLen"}, {"reply", txtTopicID.getText(), "4", textAreaReplyMessage.getText() , "1", ((Integer)remLen).toString()}});
Then:
Based on users input, it will wait for however many seconds(txtWait1) and THEN repeat the posting code above until it has reached bumpNum.
And it will update txtLog with the following EACH TIME it bumps(so the program cannot be frozen):
txtLog.append("Board Bumped. Waiting "+ ((Integer)(wait/1000)).toString() +" Seconds..." + "\n");
Edit:
Sigh. Ok, now I understand. I don't know the answer. You are talking about drawing a GUI element. I suspect you want to fork a thread to do a job and then show the GUI display that you are waiting for it. You need to wait for the thread to finish (see my join code below) all of the time having the GUI element refresh UNTIL it finishes when you display some result.
This depends more on the GUI code than sleep/timer. I would start a new question now and explain !!!NOT WITH CODE!!! but with pseudo code from 1000 foot view what you want. Something like:
I am trying to fork a thread that runs in the background in [Swing/Android/etc]. I want to display to the user that the thread has been forked, I want the user interface to wait for the thread without freezing, and then I want the user interface to join with the thread and display the results.
Think about the problem like we have to think of it. Anticipate questions that we will ask. Figure out what we don't and can't know about your environment.
Best of luck.
Edit:
If you are just trying to call sleep then you don't need to fork a thread for that. All you need to do in your code is:
try {
Thread.sleep(waitingTime);
System.out.println(waitingTime);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
This will pause the current thread (which could be the main thread) for waitingTime milliseconds.
So you are forking 3 threads very quickly which I guess you don't want to do. If you are trying to wait for each thread to finish then you will have to do something like:
Thread thread = new Thread(new Counter(wait));
thread.start();
thread.join();
Couple of other comments:
It is considered bad form to start a thread in the constructor of a class: new Thread(this).start();
You are creating 2 thread objects inside of your Runnable. You should just create one outside of your Runnable. See above.
Thread myCounter = new Thread(this); << #1
public Counter(int waitingTime) {
new Thread(this).start(); << #2
}
I would not initialize waitingTime = 0; when defined and initialize it in the constructor. This is confusing. Remove the = 0.
int waitingTime; << remove the =0 here
public Counter(int waitingTime) {
this.waitingTime = waitingTime;
When you catch InterruptedException, be sure to handle it right. A good pattern is to reset the interrupt flag and/or quit the thread:
} catch (InterruptedException e) {
// resets the interrupt flag cleared by catching the exception
Thread.currentThread.interrupt();
// or stops the thread immediately
return;
}
You're starting a new thread each time through the loop. Rather than creating a new thread in the constructor, move the do/while loop into a normal method rather than the run method of a new thread. What you're doing is spawning a new thread that does in fact sleep, but it's not the thread that's executing the loop so that thread just continues as normal.