Jump to content

Using synchronized() to your advantage


Vilius

Recommended Posts

So, I have seen people struggle pausing their scripts while their gui is open.

Sometimes they try using a boolean

public void onStart(){
	gui.initComponents()
	pause = true;
}

public int onLoop(){
	if(pause == false){
		//do stuff
	}
}

In theory it works, but its not really what you want to do, do you?

You essentially want to halt the scripts thread from working until the gui is closed or the start button is pressed, because you only want it to start doing stuff only after the user has his settings done

 

so this is where synchronization of objects comes into play.

 

we just add this to your main class:

public class Main extends Script{

	Object lock = new Object();

	public void onStart(){
		GUI.initComponents();
		synchronized(lock){
			lock.wait();
		}
	}

	public int onLoop(){
		return 100;
	}
}

And it halts the thread.

 

When a thread invokes a synchronized statement, it automatically acquires the intrinsic lock for that method's object and releases it when the method returns.

 

Every object has an intrinsic lock associated with it. A thread that needs exclusive and consistent access to an object's fields has to acquire the object's intrinsic lock before accessing them, and then release the intrinsic lock when it's done with them.

 

But now you are asking how is my gui functioning if my script is halted? Its because the gui will be handled on another thread which the synchronized statement doesn't affect.

 

Alright, so we know we halted our script thread, now what?

We need to start it again, so we know our gui is handled on another thread which is not affected by the synchronized statement, which in term would mean the thread is "free" to do anything with the object

 

So we just do this on the button:

JButton button = new JButton("Start");
frame.add(button);
button.addActionListener{e ->{
	synchronized(main.lock){
		main.lock.notify();
	}
	frame.setVisible(false);
}

as we notify the object, the object now releases its intrinsic lock and lets the script thread run as normal as before the lock.

 

Hope you learned something. If I have made mistakes feel free to correct me :)

  • Like 9
Link to comment
Share on other sites

Synchronized blocks are a bit old-fashioned and verbose IMO, I would recommend using the java.util.concurrent package where possible.

The Reentrant Lock object basically encapsulates the behavior you are describing in a simple object you can pass around more easily.

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockExample {
	
	public static void main(String[] args) {
		new Script().onStart();
	}
	
	 private static class Script {
		 
		private Gui gui;
		
		public void onStart() {
			Lock lock = new ReentrantLock();
			gui = new Gui(lock);
			new Thread(gui).start();
			System.out.println("Script pre-lock");
			lock.lock();
			System.out.println("Script post-lock");
		}
		 
	 }
	 
	 private static class Gui implements Runnable {
		 
		 private final Lock lock;
		 
		 public Gui(Lock lock) {
			this.lock = lock;
		}
		 
		 @Override
		public void run() {
			 lock.lock();
			 /*
			  * Simulate user behavior.
			  */
			 for (int i = 1; i < 4; i++) {
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("Gui has had the lock for " + i + " seconds");
			}
			 onFinalAction();
		}
		 
		 public void onFinalAction() {
			 lock.unlock();
		 }
		 
	 }
	
}
Script pre-lock
Gui has had the lock for 1 seconds
Gui has had the lock for 2 seconds
Gui has had the lock for 3 seconds
Script post-lock
  • Like 2
Link to comment
Share on other sites

The issue with freezing the script thread is your freezing your RuneScape character. Over a certain period of time idling, your character will log out. What's better (in my opinion) is to continue on to the loop, but to not to execute any tasks until the script has the user's input. Just shake the camera around a bit to keep the user logged in.  I've detailed my way of handling guis here. I hope it helps.

Edited by liverare
Link to comment
Share on other sites

  • 1 month later...

The issue with freezing the script thread is your freezing your RuneScape character. Over a certain period of time idling, your character will log out. What's better (in my opinion) is to continue on to the loop, but to not to execute any tasks until the script has the user's input. Just shake the camera around a bit to keep the user logged in.  I've detailed my way of handling guis here. I hope it helps.

If it takes that long to setup the GUI you most likely are over complicating it

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...