Programação Concorrente/Paralela em Java • Resolução do Exercício 1 public class Cont extends Thread { protected int ct; public Cont() { ct=0; } public synchronized void inc() { ct++; } public void run() { for (int i=0; i<100; i++) { inc(); System.out.print(" i= " + ct); } } public static void main(String[] arg) { System.out.print("\nSequencial"); new Cont().run(); new Cont().run(); System.out.print("\nParalelo"); new Cont().start(); new Cont().run(); } } • Resolução do Exercício 2 public class MyClock extends Thread { public MyClock() { start(); } public void run() { for(int i=0; i<10; i++) { // durante 10 segundos try { sleep(1000); } catch (InterruptedException e) {} System.out.println(i + " segundos"); } System.out.println("terminou"); } public static void main(String[] arg) { new MyClock(); } } Arquitecturas Paralelas I 13 © João Luís Sobral 2002 Programação Concorrente/Paralela • Resolução do Exercício 3 // Versão do contador com indicação de falha public class CannotIncException extends Exception { } public class CannotDecException extends Exception { } public class Cont1 { private int ct; public void Cont1() { ct=0; } public void inc() throws CannotIncException { if (ct==100) throw new CannotIncException(); else ct++; } public void dec() throws CannotDecException { if (ct==0) throw new CannotDecException(); else ct--; } } // Versão com métodos guardados com base no estado físico public class Cont2 { private int ct; public void Cont2() { ct=0; } public synchronized void inc() { while (ct>=100) { try { wait(); // suspende até ser acordado por um dec } catch(InterruptedException e) {} } ct++; if (ct==1) notifyAll(); // para acordar os que suspenderam em dec } public synchronized void dec() { while (ct<=0) { try { wait(); } catch(InterruptedException e) {} } ct--; if (ct==99) notifyAll(); } } Arquitecturas Paralelas I 14 © João Luís Sobral 2002 Programação Concorrente/Paralela • Resolução do Exercício 3 (continuação) // Versão com métodos guardados com base no estado lógico public class Cont3 { private int ct; private String estado; public void Cont3() { ct=0; estado = "min"; } public synchronized void inc() { while (estado=="max") { try { wait(); // suspende até ser acordado por um dec } catch(InterruptedException e) {} } if (estado=="min") { notifyAll(); estado="med"; } ct++; if (ct==100) estado="max"; } public synchronized void dec() { while (estado=="min") { try { wait(); } catch(InterruptedException e) {} } if (estado=="max") { notifyAll(); estado="med"; } ct--; if (ct==0) estado="min"; } } Arquitecturas Paralelas I 15 © João Luís Sobral 2002 Programação Concorrente/Paralela • Resolução do Exercício 4 // Counter.java public interface Counter extends Remote { void count() throws RemoteException; } // CounterServer.java import java.rmi.*; import java.rmi.server.*; public class CounterServer extends RemoteObject implements Counter { public void count() throws RemoteException { for(int i=0; i<100; i++) System.out.print(i + " "); } } // CounterServerApp.java import javax.naming.*; import javax.rmi.PortableRemoteObject; public class CounterServerApp { public static void main(String args[]) { try { CounterServer cs1 = new CounterServer(); PortableRemoteObject.exportObject(cs1); CounterServer cs2 = new CounterServer(); PortableRemoteObject.exportObject(cs2); Context ctx = new InitialContext(); ctx.rebind("CounterServer1",cs1); ctx.rebind("CounterServer2",cs2); BufferedReader rdr = new BufferedReader(new InputStreamReader(System.in)); while (true) { System.out.println("Type EXIT to shutdown the server"); if ("EXIT".equals(rdr.readLine())) { break; } } ctx.unbind("CounterServer1"); ctx.unbind("CounterServer2"); PortableRemoteObject.unexportObject(cs1); PortableRemoteObject.unexportObject(cs2); } catch(Exception e) { e.printStackTrace(); } } } Arquitecturas Paralelas I 16 © João Luís Sobral 2002 Programação Concorrente/Paralela • Resolução do Exercício 4 (continuação) // AssCounter.java public class AssCounter extends Thread { Counter myCount; public AssCounter(Counter c) { myCount =c; } public void run() { try { myCount.count(); } catch(Exception ex) { } ex.printStackTrace(); } } // CounterClient.java import javax.naming.*; import java.util.*; public class CounterClient { public static Counter findCounter(String cnt, Context ctx) { Counter cs=null; try { cs = (Counter) PortableRemoteObject.narrow( ctx.lookup(cnt), Counter.class); } catch(Exception ex) { ex.printStackTrace(); } return(cs); } public static void main(String args[]) { try { Context ctx = new InitialContext(); Counter cs1 = findCounter("CounterServer1",ctx); Counter cs2 = findCounter("CounterServer2",ctx); // Execução sequencial cs1.count(); cs2.count(); // Execução em paralelo (new AssCounter(cs1)).start(); cs2.count(); } catch(Exception ex) { ex.printStackTrace(); } } } Arquitecturas Paralelas I 17 © João Luís Sobral 2002 Programação Concorrente/Paralela • Resolução do Exercício 5. São alteradas as classes AssCounter e CounterClient e é adicionado a interface Callback: // Callback.java public interface Callback { void callOP(); } // AssCounter.java public class AssCounter extends Thread { Counter myCount; Callback myClient; public AssCounter(Counter c, Callback cl) { myCount =c; myClient = cl; } public void run() { try { myCount.count(); } catch(Exception ex) { myClient.callOP(); } ex.printStackTrace(); } } // CounterClient.java public class CounterClient implements Callback { public void try { Context Counter Counter execute() { ctx = new InitialContext(); cs1 = findCounter("CounterServer1",ctx); cs2 = findCounter("CounterServer2",ctx); // Execução em paralelo new AssCounter(cs1,this).start(); new AssCounter(cs2,this).start(); } catch(Exception ex) { ex.printStackTrace(); } } public void callOP() { System.out.println("Done"); } public static void main(String args[]) { new CounterClient().execute(); } } Arquitecturas Paralelas I 18 © João Luís Sobral 2002 Programação Concorrente/Paralela • Resolução do Exercício 6 // Counter.cs using System; using System.Runtime.Remoting.Messaging; public abstract class Counter: MarshalByRefObject { public abstract void count(); } // CounterServer.cs using using using using using using System; System.Runtime.Remoting; System.Runtime.Remoting.Channels.Http; System.Runtime.Remoting.Channels; System.Runtime.Remoting.Messaging; System.Threading; class CounterServer : Counter { public override void count() { for(int i=0; i<100; i++) { Console.Write(i + " "); Thread.Sleep(50); } Console.WriteLine(); } } class ServerStartup { static void Main(string[] args) { Console.WriteLine ("ServerStartup.Main(): Server started"); HttpChannel chnl = new HttpChannel(1234); ChannelServices.RegisterChannel(chnl); RemotingConfiguration.RegisterWellKnownServiceType( typeof(CounterServer), "CounterServer.soap", WellKnownObjectMode.Singleton); // the server will keep running until keypress. Console.ReadLine(); } } Arquitecturas Paralelas I 19 © João Luís Sobral 2002 Programação Concorrente/Paralela • Resolução do Exercício 6 (continuação) // CounterClient.cs using using using using using using System; System.Runtime.Remoting; System.Runtime.Remoting.Channels.Http; System.Runtime.Remoting.Channels.Tcp; System.Runtime.Remoting.Channels; System.Runtime.Remoting.Proxies; class CounterClient { delegate void CounterDelegate(); static void Main(string[] args) { HttpChannel channel = new HttpChannel(); ChannelServices.RegisterChannel(channel); Counter obj = (Counter) Activator.GetObject( typeof(Counter), "http://localhost:1234/CounterServer.soap"); Console.WriteLine("Client.Main(): Reference to rem.obj. acquired"); // execução sequencial obj.count(); obj.count(); // execução em paralelo CounterDelegate cDel1 = new CounterDelegate(obj.count); IAsyncResult svAsy1 = cDel1.BeginInvoke(null,null); Console.WriteLine("Client.Main(): Invocation1 done"); CounterDelegate cDel2 = new CounterDelegate(obj.count); IAsyncResult svAsy2 = cDel2.BeginInvoke(null,null); Console.WriteLine("Client.Main(): Invocation2 done"); try { cDel1.EndInvoke(svAsy1); Console.WriteLine("EndInvoke1 returned successfully "); } catch (Exception e) { Console.WriteLine("EXCEPTION during EndInvoke1"); } try { cDel2.EndInvoke(svAsy2); Console.WriteLine("EndInvoke2 returned successfully"); } catch (Exception e) { Console.WriteLine("EXCEPTION during EndInvoke2"); } // wait for keypress Console.ReadLine(); } } Arquitecturas Paralelas I 20 © João Luís Sobral 2002