import java.sql.SQLException; import java.util.Random; import sqlj.runtime.ExecutionContext; import oracle.sqlj.runtime.Oracle; /** Each instance of MultiThreadDemo is a thread that gives all employees a raise of some ammount when run. The main program creates two such instances and computes the net raise after both threads have completed. **/ class MultiThreadDemo extends Thread { double raise; static Random randomizer = new Random(); public static void main (String args[]) { try { /* if you're using a non-Oracle JDBC Driver, add a call here to DriverManager.registerDriver() to register your Driver */ // set the default connection to the URL, user, and password // specified in your connect.properties file Oracle.connect(MultiThreadDemo.class, "connect.properties"); double avgStart = calcAvgSal(); MultiThreadDemo t1 = new MultiThreadDemo(250.50); MultiThreadDemo t2 = new MultiThreadDemo(150.50); t1.start(); t2.start(); t1.join(); t2.join(); double avgEnd = calcAvgSal(); System.out.println("average salary change: " + (avgEnd - avgStart)); } catch (Exception e) { System.err.println("Error running the example: " + e); } } static double calcAvgSal() throws SQLException { double avg; #sql { SELECT AVG(sal) INTO :avg FROM emp }; return avg; } MultiThreadDemo(double raise) { this.raise = raise; } public void run() { // Since all threads will be using the same default connection // context, each run uses an explicit execution context instance to // avoid conflict during execution try { delay(); ExecutionContext execCtx = new ExecutionContext(); #sql [execCtx] { UPDATE EMP SET sal = sal + :raise }; int updateCount = execCtx.getUpdateCount(); System.out.println("Gave raise of " + raise + " to " + updateCount + " employees"); } catch (SQLException e) { System.err.println("error updating employees: " + e); } } // delay is used to introduce some randomness into the execution order private void delay() { try { sleep((long)Math.abs(randomizer.nextInt()/10000000)); } catch (InterruptedException e) {} } }