Results 1 to 7 of 7
Like Tree2Likes
  • 1 Post By quad64bit
  • 1 Post By SJF

Thread: Help sharing objects between threads!

  1. #1
    pepzi999 is offline Member
    Join Date
    Oct 2012
    Posts
    2
    Rep Power
    0

    Default Help sharing objects between threads!

    I have two threads in my game; one that calls the update method of each class (for example Player, platform, etc.) and another one that calls the paint method of each class. It's just for the game to run faster when a lot of things are happening.

    Now, I've gotten to the point where I can run the update thread in which the objects (the ones above) are initiated and updated, but the thread for painting which extends the update thread won't get the updated variables for the objects, in fact I can't seem to even update a simple int from the update thread and get it to the paint thread. So what I'm asking is how do you get the updated variables/objects from a thread to another thread?

    Will post code if necessary.

  2. #2
    quad64bit's Avatar
    quad64bit is offline Moderator
    Join Date
    Jul 2009
    Location
    VA
    Posts
    1,323
    Rep Power
    7

    Default Re: Help sharing objects between threads!

    First off, I doubt very much that you're gaining a lot of performance here by multi threading. Painting tends to be one of the slower parts of game code in java - if you profile I'm curious what you see? There are also a huge number of other problems that can occur with concurrency. How are you accessing your data? Do you have accessors? Are you using synchronized methods, object locks, mutex/semaphores?

    Generally, your game logic only takes a fraction of the time a frame draw does. Many games perform the logic first in the main game loop, then draw. This makes things many times simpler.

  3. #3
    SJF
    SJF is offline Senior Member
    Join Date
    Oct 2012
    Posts
    108
    Rep Power
    0

    Default Re: Help sharing objects between threads!

    Performance gain aside, you'll run into some issues using int across threads:

    BROKEN CODE:
    Java Code:
    public class Sandbox {
    	private static int x;
    	
    	private static class MyThread extends Thread{
    
    		private int myThreadNum;
    		
    		MyThread(int threadNum){
    			myThreadNum = threadNum;
    		}
    		
    		public void run(){
    			for(int i = 0; i < 100; i++){
    				System.out.println("Thread " + myThreadNum + " : x = " + x++);   //This will not end well.
    			}
    		}
    		
    		
    	}
        public static void main(String args[]){
        	Thread t1 = new MyThread(1);
        	Thread t2 = new MyThread(2);
        	x=0;
        	
        	t1.start();
        	t2.start();
        }   
    }
    If you run this a few times, you'll see x does not always increment properly. Why? Thread X increments x after thread Y read x. It's THE most basic problem with concurrency: interleaving.

    Java has some classes that can help: Atomic variables.
    Java Code:
    import java.util.concurrent.atomic.AtomicInteger;
    
    public class Sandbox {
    	private static AtomicInteger x;
    	
    	private static class MyThread extends Thread{
    
    		private int myThreadNum;
    		
    		MyThread(int threadNum){
    			myThreadNum = threadNum;
    		}
    		
    		public void run(){
    			for(int i = 0; i < 100; i++){
    				System.out.println("Thread " + myThreadNum + " : x = " + x.getAndIncrement());     //The AtomicInteger has a built-in mutex (so-to-speak).
    			}
    		}
    		
    		
    	}
        public static void main(String args[]){
        	Thread t1 = new MyThread(1);
        	Thread t2 = new MyThread(2);
        	x = new AtomicInteger(0);
        	
        	t1.start();
        	t2.start();
        }   
    }
    FIX'D

    For now.... read up on Mutexes / Semaphores, it'll help. Sorry I don't have a good link off the top of my head to get to you.


    NOTE: there is no guarantee here that 0-199 will be printed in order, just that x will eventually get to 199.
    Last edited by SJF; 10-25-2012 at 03:41 AM.

  4. #4
    pepzi999 is offline Member
    Join Date
    Oct 2012
    Posts
    2
    Rep Power
    0

    Default Re: Help sharing objects between threads!

    Quote Originally Posted by SJF View Post
    Performance gain aside, you'll run into some issues using int across threads
    Ok, I've heard about atomic integers but my main problem is still that I want to call two different methods of an object in two different threads, something like this:



    The update-thread (started from another thread) in which my objects are initiated

    Java Code:
    public class UpdateThread extends MainThread implements Runnable {
    
    	
    		private boolean running;
    		TestPlayer p1;
    		Platform plat, plat2, plat3, plat4, plat5;
    		Camera cam;
    		String message;
    		
    
    		public void stop(){
    			setRunning(false);
    		}
    	
    		public void run(){
    			
    			System.out.print("Got there");
    			start(); 
    			try{	
    			Runnable paint = new PaintThread();
    			Thread paintThread = new Thread(paint);
    			paintThread.start();
    
    			while(running){
    			gameLoop();
    			}
    			
    			}catch(Exception e){
    				
    			}finally{ stop();
    			
    			}
    			
    			
    		}
    		
    
    		public void start(){
    			
    			p1 = new TestPlayer();
    			plat = new Platform(-2000, 850, 5000, 400);
    			plat2 = new Platform(900, 220, 100, 200);
    			plat3 = new Platform(700, 620, 100, 200);
    			plat4 = new Platform(800, 330, 200, 600);
    			cam = new Camera();
    			setRunning(true);
    	        }
    		
    		
    		
    	
    		
    		public void gameLoop(){
    			
    				p1.update(this, cam); //Rangordna efter prioritet
    				plat2.update(this, p1, cam); //, snail, stoneList);
    				plat3.update(this, p1, cam); //, snail, stoneList);
    				plat4.update(this, p1, cam); //, snail, stoneList);
    				cam.update(this, p1);
    			
    				try{
    					Thread.sleep(17); // 20
    				}catch(Exception ex){}
    											
    		}
    
    		public boolean isRunning() {
    			return running;
    		}
    
    		public void setRunning(boolean running) {
    			this.running = running;
    
    		}
    The thread for painting:

    Java Code:
    
    public class PaintThread extends UpdateThread implements Runnable, ImageObserver {
    		
    		private static DisplayMode modes[] = {
    			new DisplayMode(1950, 1080, 32, 0),
    			/*new DisplayMode(1920, 1080, 24, 0),
    			new DisplayMode(1920, 1080, 16, 0),
    			new DisplayMode(1600, 1200, 32, 0),
    			new DisplayMode(1600, 1200, 24, 0),
    			new DisplayMode(1600, 1200, 16, 0),
    			*/
    		};
    			
    			boolean paintRunning;
    			private Image bg;
    			private Image player;
    			int width;
    			TestPlayer paintP1;
    			int backgroundX = 0;
    			int backgroundY = 0;
    			int height;
    			Pictures p = new Pictures(this);
    			
    			
    			public void stop(){
    				paintRunning = false;
    			}
    			
    			
    			public void loadImages(){
    				bg = new ImageIcon("C:\\Munin\\Bakgrund.png").getImage();
    			}
    			
    		
    			
    		
    			public void run(){
    	
    				try{
    					
    					init();
    					loadImages();
    				
                                            while(paintRunning){
    
    					paintLoop();
    
    					}
    
    						
    						
    				}finally{
    					s.restoreScreen();
    					System.out.print("STOP");
    				}
    				
    			
    			}
    		
    			public void init(){
    				s = new Screen();
    				DisplayMode dm = s.findFirstCompatibleDisplayMode(modes);
    				s.setFullScreen(dm);
    				Window w = s.getFullScreenWindow();
    				width = s.getWidth();
    				height = s.getHeight();
    				paintRunning = true;
    			}
    			
    			public void paintLoop(){
    			
    					Graphics2D g = s.getGraphics();
    					paint(g);
    					g.dispose();
    					s.update();
    					
    					try{
    						Thread.sleep(20);
    					}catch(Exception ex){}
    					
    		
    				
    			}
    			
    			
    			
    			public void paint(Graphics g){
    				
    				g.drawImage(bg, backgroundX, backgroundY, null);
    				p1.paint(g); //This causes a java.lang.NullPointerException, even just trying to System.out.print another method like p1.getDx() leads to this.
    				                 //And if I remove this line the next line will do the same.
    				
    				plat.paint(g);
    				plat2.paint(g);
    				plat3.paint(g);
    				plat4.paint(g);
    				cam.paint(g, p1);
    				System.out.println("Paint Thread says hello aswell");
    			
    			}
    
    
    		
    			public int getResolutionX(){
    				
    				return width;
    				
    			}
    			
    			public int getResolutionY(){
    				return height;
    			}
    			
    			
    		
    	}
    So, I heard something about doing this:

    "synchronized(p1){

    p1.paint(g);

    }"

    but that doesn't work either, so what shall I do?
    Last edited by pepzi999; 10-25-2012 at 01:02 PM.

  5. #5
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,452
    Rep Power
    20

    Default Re: Help sharing objects between threads!

    Quote Originally Posted by pepzi999 View Post
    Java Code:
    			public void run(){
    	
    					
    				try{
    					
    				
    						init();
    								
    				
    					
    						
    						loadImages();
    				
    		
    					
    						while(paintRunning){
    						paintLoop();
    						}
    
    						
    						
    				}finally{
    					s.restoreScreen();
    					System.out.print("STOP");
    				}
    				
    			
    			}
    Please edit your post and remove the excess vertical whitespace which makes the code difficult to follow. Use whitespace as recommended in Code Conventions for the Java Programming Language: Contents

    db
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  6. #6
    quad64bit's Avatar
    quad64bit is offline Moderator
    Join Date
    Jul 2009
    Location
    VA
    Posts
    1,323
    Rep Power
    7

    Default Re: Help sharing objects between threads!

    So, I heard something about doing this:

    "synchronized(p1){

    p1.paint(g);

    }"

    but that doesn't work either, so what shall I do?
    So if you don't understand how synchronization works yet, then you should be experimenting with threads in a simpler project. I'll reiterate that threading in this case is more than likely just making the game design overly complex without appreciable benefit. I'd like to also point out, that because of synchronization, you might actually substantially slow your game down since threads can spend a large amount of time waiting for locks to release.

    If you want to make a game, start with a single threaded version and really polish it. If and only if there is an issue, then analyze that. If threading makes sense, then approach that. Premature 'optimization' is the root of many failed projects, or many impossible to maintain/extend projects.

    If you are really interested in threading, start experimenting in a new app that doesn't have all the complexity of a game behind it. Write tests. Read how locks and synchronization actually work. Understand the problems associated with multi-threaded programming (concurrent data exceptions, deadlock, starvation, data corruption from concurrent modifications, etc...). Also, read this: Lesson: Concurrency (The Java™ Tutorials > Essential Classes)

    Proper multi-threaded programming is hard. For your first projects, it will almost undoubtedly cause more problems than it solves, because you don't appreciate how it actually works, what it aims to solve, and the problems it creates (which require a fair amount of engineering and planing to work around).

    It took me a couple years of playing the threading before I actually did anything really useful with it, and I found looking back that many of my early attempts could actually be rewritten faster and more simply using single threaded techniques and better design. Threading always has a place in GUIs and client server apps, and the like, but for most applications, it really isn't needed.
    Fubarable likes this.

  7. #7
    SJF
    SJF is offline Senior Member
    Join Date
    Oct 2012
    Posts
    108
    Rep Power
    0

    Default Re: Help sharing objects between threads!

    I agree with quad64bit on most of what he's said...

    Many games will require threading to some extent regardless... I'm not entirely sure that you need syncronization...

    p1.paint(g); //This causes a java.lang.NullPointerException, even just trying to System.out.print another method like p1.getDx() leads to this.
    //And if I remove this line the next line will do the same.
    NPE here indicates that p1 is not initialized, and it's not for paint thread! You'll need to pass a reference to the paint thread of the player to get this to work. (in the constructor.... or have this as a child class of main thread, and make sure it is initialized prior to calling methods on it).

    If you're updating the player in one thread, and drawing it in another, you should worry so much about concurrency so much (some interactions may not get drawn, but that's a minor point right now). You're not even to the point of worrying about locking one thread out while the other works on a variable, your paint thread can't see the player at all.

    If you're just trying to learn game design, you may want to look into some free game engines out there that handle the timing for you and help you focus on creating your game. (Sorry I can't offer a recommendation here as I don't know the java engines). Good luck!


    Info on syncronized:
    Synchronized methods prevent interleaving on an object's methods (not the object.. thread 1 can perform a obj.write() and interleave on thread 2's obj.read() for example) Synchronized Methods (The Java™ Tutorials > Essential Classes > Concurrency)...
    Fubarable likes this.

Similar Threads

  1. Threads per Connection or Threads per Request
    By Felic in forum New To Java
    Replies: 4
    Last Post: 11-22-2011, 10:15 PM
  2. Problem with sharing objects in different lists
    By AmFreak in forum New To Java
    Replies: 20
    Last Post: 07-07-2011, 04:03 PM
  3. Passing Objects Between Threads -->
    By shuks in forum Threads and Synchronization
    Replies: 9
    Last Post: 08-27-2010, 09:22 PM
  4. what is the best ADT to use in p2p sharing
    By a_maged in forum Networking
    Replies: 0
    Last Post: 12-02-2007, 09:15 PM
  5. 2 threads sharing a data base connection
    By Ed in forum Advanced Java
    Replies: 2
    Last Post: 07-04-2007, 05:41 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •