• 0

[JAVA] Saving integers from a thread


Question

Hey,

I'm currently doing my assignment, which is a client, server network application. A concurrent server.

Its a concurrent server, and works perfectly for general communication. However i have to store how many times the file has been 'downloaded'.

The server works by creating a thread upon a successful connection. The server then has to print out how many times a file has been downloaded after its downloaded.

The thread when a file is downloaded calls a method in the server to increment the download count. However because its seperate threads when multiple clients connect it doesnt increment the updated number that another client might have set.

Output from my IDE to show what i mean:

Waiting for connection request...

Creating a new thread

Number of threads running: 1

Waiting for connection request...

File 1 has been downloaded 1 times.

Creating a new thread

Number of threads running: 2

Waiting for connection request...

File 1 has been downloaded 1 times.

Obviously File 1 should have been downloaded 2 times.

Any way to fix this?

Thanks,

David

Link to comment
https://www.neowin.net/forum/topic/706174-java-saving-integers-from-a-thread/
Share on other sites

13 answers to this question

Recommended Posts

  • 0

Yeah the integer is a int[], part of the main class.

Relevant code

Main

  public void setDownload(int fileNo) {
	int[] downloadCount = new int[files.length];
	downloadCount[fileNo]++;
	System.out.println(files[fileNo] + " has been downloaded " + downloadCount[fileNo] + " times.");
  }

Thread Instance

case 4:
					out.println("You are downloading " + files[3]);
					serverObject.setDownload(3);
					state = 2;
					break;

  • 0

btw: you have a serious programming problem...

you should only have one server instance, but you seem to have multiple.... so in other words my above fix is not the right solution even though it works.

you should use the singleton pattern to get the server instance and ensure there is only ever one server instance... so do this code instead.

public class ServerObject {
private int[] downloadCount; // note: no longer static

private static ServerObject instance; // the server instance is now static

private ServerObject() {
   // hide the default constructor from everyone except this class
}

public static ServerObject getInstance() {
   if (instance == null) {
	  instance = new ServerObject(); // only called once, so ensures only one server instance.
   }
  return instance;
}
}

out.println("You are downloading " + files[3]);
					ServerObject.getInstance().incrementDownloadCounter(3);
					state = 2;
					break;

// you no longer need to call new ServerObject() - just call  ServerObject.getInstance() anywhere in your code. you dont even need to pass it in as a parameter.

  • 0

no, if you implement the singleton pattern as shown above, you can only ever have one instance of the server object.

calling getInstance() ensure that every thread in the JVM will always reference the same server object.

notice the "static ServerObject instance" declaration. it ensures that all instance of Server object are shared - hence "static"

now we ensure that only one server object can ever exist by making the constructor "private ServerObject()" and

creating the static method

public static ServerObject getInstance() {

if (instance == null) {

instance = new ServerObject(); // only ever called once, so ensures only one server instance.

}

return instance;

}

here is your code at the moment - hence why you had the download count problem.

[server] -> [worker thread]
[server] -> [worker thread]
[server] -> [worker thread]
[server] -> [worker thread]
[server] -> [worker thread]
[server] -> [worker thread]

here is the singleton pattern applied to the server

				|- [worker thread]
				|- [worker thread]
	[server]----|- [worker thread]
				|- [worker thread]
				|- [worker thread]
				|- [worker thread]

  • 0

One more issue, when putting the client into a GUI, which is continuously checking for user input and server input. The GUI doesnt add all the components. This is because I have made it so that the main method contains a while loop, that is checking for server input.

What would be the best way to put it into a GUI, so that the text area updates with all server input? This is the following code, which checks for messages from the server.

		while ((fromServer = in.readLine()) != null) {
			System.out.println("Server: " + fromServer);
		}

  • 0

Thanks i have made quite a bit of progress with that advice.

It now updates the text field with the first input from the server, but because its not in a loop, it doesnt update it.

Again, if i put it in the loop, the frame doesnt paint.

This is my code.

Client

  public static void main(String args[]) {
	// read from server
	thread.start();

	java.awt.EventQueue.invokeLater(new Runnable() {

	  public void run() {
		new Client().setVisible(true);
		  text = ClientThread.getOutputText();
		  setServerText(text);
	  }
	});
  }

  public static void setServerText(String text) {
	textOutput.setText(text);
  }

ClientThread

  @Override
  public void run() {   
	try {
	  while ((fromServer = in.nextLine()) != null) {
		setOutputText("Server: " + fromServer);
	  }
	} catch (NoSuchElementException ex) {
	}
  }

  public void setOutputText(String textInput) {
	serverOut = textInput;
  }

  public static String getOutputText() {
	return serverOut;
  }

The Client definately communicates with the server, as i can see the messages passed in the output dialog of my IDE, from my setOutputText method. I just need a loop for the GUI to update.

Edited by dave164
  • 0

try setting thr thread to sleep for a little bit in your while loop.

Thread.sleep(500);

also you should not be doing this stuff in the main. you should be creating an instance of the class!!!!

ie.

  public static void main(String args[]) {
		ClientApplication clientApplication = new ClientApplication();
	}

  public ClientApplication(String text) {
	this.setVisible(true);
   java.awt.EventQueue.invokeLater(new WorkerThread(this));

}

  public void setServerText(String text) {
	textOutput.setText(text);
  }


class WorkerThread implements Runnable{

  private ClientApplication clientApp;

   public WorkerThread(ClientApplication clientApp) {
	 this.clientApp = clientApp;
   }

   public run() {

	 while (!this.clientApp.isCloseConnectionState())
		 try {  
		 this.clientApp.setTextOutput(..... put txt here)   
		 Thread.sleep(500);
		} catch() {
		   throw runtimeException(e);
		 }
	 }
}

note: code above wont work as you need to code this yourself. and I dont have a compiler on hand

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • Did Labour lose big? They had losses there is no doubt. However let's look at the reality. The conservatives have 168 councils I believe. Labour have 113 and Reform...38. That's a lot of growth for Reform granted. But that is not a wipeout, Reform don't have the majoring in fact at 76 I believe the Liberal Democrats have nearly twice the councils Reform do. So I am thinking there is a lot more noise than signal going on here. Now then let's talk about the law. It's an age restriction. We do it for cigarettes, **** and alcohol. This idea that some kids will find there way around it so it's not worth even trying is really really sad. Hell we can't stop every murder. Should we stop trying there too? That is the logical conclusion.
    • A game not selling doesn't mean the people working on it did "bad work". It reviewed decently well. It was also on gamepass on release.
    • PDF Shaper 15.6 by Razvan Serea PDF Shaper is a set of feature-rich PDF software that makes it simple to split, merge, watermark, sign, optimize, convert, encrypt and decrypt your PDF documents, also delete and move pages, extract text and images. The program is optimized for low CPU resource usage and operates in batch mode, allowing users to process multiple PDF files while doing other work on their computers. PDF Shaper is available in three editions - Free, Premium and Ultimate. Compare and pick edition which is suitable for you. Compatible with Windows 7, 8, 10, 11. Features: Convert PDFs to Word, text, or image files (and vice versa) Merge, split, and watermark documents with precision Insert, move, delete, rotate and crop pages/ranges Rename and organize PDF collections efficiently Encrypt with advanced AES password protection Apply multiple digital signatures for documents Extract text, images, or complete pages from any PDF Benefits: Easy-to-use, intuitive user interface Low CPU resource usage during any process, including conversion Free for personal use and for any non-commercial organization Supports Unicode characters Supports batch processing for any operation Small installation size PDF Shaper 15.6 changelog: Improved overall program performance. Improved image rendering in all tools. Improved XMP information extraction. Improved compatibility with ARM64 systems. Improved DOC to PDF conversion: Improved support for font files. Improved support for picture cropping. Improved support for list formatting. Improved support for text line spacing. Download: PDF Shaper 15.6 | 8.0 MB (Free for personal use only) Link: PDF Shaper Home Page | Screenshot Get alerted to all of our Software updates on Twitter at @NeowinSoftware
  • Recent Achievements

    • One Year In
      Console General earned a badge
      One Year In
    • One Year In
      Twozo Technologies earned a badge
      One Year In
    • One Month Later
      Twozo Technologies earned a badge
      One Month Later
    • Week One Done
      Twozo Technologies earned a badge
      Week One Done
    • Veteran
      branfont went up a rank
      Veteran
  • Popular Contributors

    1. 1
      +primortal
      533
    2. 2
      +Edouard
      206
    3. 3
      PsYcHoKiLLa
      130
    4. 4
      Steven P.
      90
    5. 5
      neufuse
      74
  • Tell a friend

    Love Neowin? Tell a friend!