Jump to content

Using synchronized() to your advantage


Recommended Posts

Posted

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
Posted

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
Posted (edited)

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
  • 1 month later...
Posted

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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

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