RMI:如何创建线程?

时间:2012-07-30 13:03:41

标签: java log4j aspectj

我很难理解哪个线程执行特定方法。服务器端有什么方法吗?我是RMI的新手。

HelloClient:

public class HelloClient 
{
    Random rand = new Random();

    public static void main(String[] args) 
    {
        Thread.currentThread().setName("Thread of a client");
        if(System.getSecurityManager() == null) 
        {
            System.setSecurityManager(new RMISecurityManager());
        }

        HelloClient hc = new HelloClient();
        hc.methodToMeasureEnglish();
    } 


    void methodToMeasureEnglish()
    {
        try
        {
            Thread.sleep(Math.abs(rand.nextInt()%4000));
            Registry reg = LocateRegistry.getRegistry("localhost", 6666);
            HelloIF hello = (HelloIF) reg.lookup("HELLO"); 
            System.out.println(hello.sayHelloEnglish());
        }
        catch( Exception e ) 
        {
            e.printStackTrace();
        }
    }
}

您好:

public class Hello extends UnicastRemoteObject implements HelloIF 
{
    public Hello(String name) throws RemoteException
    {
        try 
        {
            Registry registry = LocateRegistry.createRegistry(6666);
            registry.rebind(name, this);
        }
        catch(Exception e) 
        {
            e.printStackTrace();
        }
    }


    public String sayHelloEnglish() 
    {
        return "GOOD MORNING";
    }
}

HelloIF

public interface HelloIF extends Remote 
{
    public String sayHelloEnglish() throws RemoteException;
}

为HelloServer

public class HelloServer 
{ 
        public static void main(String[] args) throws Exception 
        {
            Thread.currentThread().setName("Server Thread");
            if(System.getSecurityManager() == null) 
            { 
                System.setSecurityManager(new RMISecurityManager()); 
            }
            Hello myObject = new Hello("HELLO");
            System.out.println( "Server is ready..." );
        }

}

我使用RMI吗?

我添加了AspectJ类

@Aspect
public class MeasureAspect 
{  
    private static Logger logger = Logger.getLogger(MeasureAspect.class);

    @Around("call(void method*())")  
    public Object condition2(ProceedingJoinPoint joinPoint) throws Throwable 
    {   
        PropertyConfigurator.configure("log4j.properties");
        Object res = joinPoint.proceed();
        logger.info("Thread method " + Thread.currentThread().getName());     
        return res;
    }  

    @Around("call(String say*())")  
    public Object condition1(ProceedingJoinPoint joinPoint) throws Throwable 
    {   
        PropertyConfigurator.configure("log4j.properties");
        Object res = joinPoint.proceed();
        logger.info("Thread say " + Thread.currentThread().getName());   
        return res;
    }  

}

所有日志都来自客户端线程。你能解释一下女巫线程执行我的方法吗?

1 个答案:

答案 0 :(得分:1)

RMI规范表示您不能对执行哪些线程远程方法做出任何假设。具体来说,这意味着几件事:

  1. 你不能认为它是单线程的。
  2. 您不能假设来自同一客户端线程的连续调用将在同一服务器线程中执行。
  3. 你不能假设它将全部在主线程中执行,而不是那有意义。
  4. 实际上,如果在服务器上有任何线程池(Oracle JVM不这样做,但我相信IBM会这样做),和/或客户端的集合池(Oracle JVM这样做,不了解IBM) ),每个方法调用都在自己的线程上执行。