首页 > 编程语言 >Java中如何动态创建接口的实现

Java中如何动态创建接口的实现

时间:2023-06-07 11:37:28浏览次数:43  
标签:调用 Java Object 接口 线程 动态创建 sleep 方法

下面用JDK动态代理加一点简单的代码来演示这个过程:

1、接口

package com.yhouse.modules.daos;
 
public interface IUserDao {
    public String getUserName();
}

2、创建代理

 

package com.yhouse.modules.daos;
 
import java.lang.reflect.Proxy;
/**
 * 创建代理
 * @author clonen.cheng
 *
 */
public class Invoker {
   
  
    public Object getInstance(Class<?> cls){       
        MethodProxy invocationHandler = new MethodProxy();       
        Object newProxyInstance = Proxy.newProxyInstance( 
                cls.getClassLoader(), 
                new Class[] { cls },
                invocationHandler);
        return (Object)newProxyInstance;
    }
}

3、运行时调用接口的方法时的实现(这一过程也称为接口的方法实现)

package com.yhouse.modules.daos;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
 
public class MethodProxy implements InvocationHandler {
 
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)  throws Throwable {       
        //如果传进来是一个已实现的具体类(本次演示略过此逻辑)
        if (Object.class.equals(method.getDeclaringClass())) { 
            try { 
                return method.invoke(this, args); 
            } catch (Throwable t) { 
                t.printStackTrace(); 
            } 
        //如果传进来的是一个接口(核心)
        } else { 
            return run(method, args); 
        } 
        return null;
    }
   
    /**
     * 实现接口的核心方法
     * @param method
     * @param args
     * @return
     */
    public Object run(Method method,Object[] args){ 
        //TODO        
        //如远程http调用
        //如远程方法调用(rmi)
        //....
       return "method call success!";
    } 
 
}

4、测试

 

package com.yhouse.modules.daos;
 
public class ProxyTest {
 
   
    public static void main(String[] args) {
        IUserDao invoker=(IUserDao)new Invoker().getInstance(IUserDao.class);
        System.out.println(invoker.getUserName());
    }
 
}

1. 进程和线程之间有什么不同?

  进程是一个独立的运行环境,它可以被看作是一个程序或者一个应用。而线程是在进程中执行的一个任务。进程是操作系统进行资源分配的基本单位,而线程是操作系统进行调度的基本单位。进程让操作系统的并发性成为可能,而线程让进程的内部并发成为可能。好比Java运行环境是一个(包含了不同的类和程序的)单一进程。

2. Thread 类中的start() 和run() 方法有什么区别?

1) start()被用来启动新的线程,run()不能。

2)start()不能被重复调用,run()可以。

3)start()中的run代码可以不执行完就继续执行下面的代码,即线程转换,如果直接调用run()必须等待其代码全部执行完才能继续执行下面的代码。

4)start()实现了多线程,run()没有实现多线程。

3. 在多线程中,什么是上下文切换?

上下文切换是存储和恢复CPU状态的过程,它使得线程执行能够从中断点恢复执行。是多任务操作系统和多线程环境的基本特征。

4. Java中的volatile 变量是什么?

volatile是一个特殊的修饰符,只有成员变量(类的成员变量、类的静态成员变量)才能使用它。

被volatile修饰之后就具备了两层语义:

1)保证了不同线程对这个变量进行操作时的可见性(即一个线程修改了某个变量的值,这新值对其他线程来说是即刻可见的)。

2)禁止进行指令重排序。

5. Java中堆和栈有什么不同?(相对于线程来说)

  栈是一块和线程紧密相关的内存区域。每个线程都有自己的栈内存,用于存储本地变量,方法参数和栈调用,一个线程中存储的变量对其它线程是不可见的。

  堆是所有线程共享的一片公用内存区域。对象都在堆里创建,为了提升效率线程会从堆中弄一个缓存到自己的栈,如果多个线程使用该变量就可能引发问题,这时volatile 变量就可以发挥作用了,它要求线程从主存中读取变量的值。

6. 什么是线程池? 为什么要使用它?

  创建线程要花费资源和时间,如果任务来了才创建线程那么响应时间会变长,而且一个进程能创建的线程数有限。为了避免这些问题,在程序启动的时候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程。

7. 死锁是什么?如何避免死锁?

死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。这是一个严重的问题,因为死锁会让你的程序挂起无法完成任务,死锁的发生必须满足以下四个条件:

1)互斥条件:一个资源每次只能被一个进程使用。

2)请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

3)不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。

4)循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

  避免死锁最简单的方法就是阻止循环等待条件,将系统中所有的资源设置标志位、排序,规定所有的进程申请资源必须以一定的顺序(升序或降序)做操作来避免死锁。

8. Thread类中的yield方法有什么作用?

Thread.yield() 方法会使当前线程从运行状态变为就绪状态,把运行机会让给其它相同优先级的线程。它是一个静态的原生(native)方法而且只保证当前线程放弃CPU占用而不能保证使其它线程一定能占用CPU,执行yield()的线程有可能会被再次继续执行的。

9. Java中notify 和 notifyAll有什么区别?

  调用notify时,只有一个等待线程会被唤醒而且它不能保证哪个线程会被唤醒,这取决于线程调度器。虽然如果你调用notifyAll方法,那么等待该锁的所有线程都会被唤醒。

10. Java中interrupted 和 isInterruptedd方法的区别?

interrupted() 和 isInterrupted()的主要区别是前者会将中断状态清除而后者不会。

Java多线程的中断机制是用内部标识来实现的,调用Thread.interrupt()来中断一个线程就会设置中断标识为true。当中断线程调用静态方法Thread.interrupted()来检查中断状态时,中断状态会被清零。而非静态方法isInterrupted()用来查询其它线程的中断状态且不会改变中断状态标识。简单的说就是任何抛出InterruptedException异常的方法都会将中断状态清零。无论如何,一个线程的中断状态有有可能被其它线程调用中断来改变。

11. Java多线程中调用wait() 和 sleep()方法有什么不同?

sleep()和wait()都是使线程暂停执行一段时间的方法。二者区别为:

1)原理不同。

sleep()方法是Thread类的静态方法,是线程用来控制自身流程的,它会使此线程暂停执行一段时间,而把执行机会让给其他线程,等到计时时间一到,此线程会自动苏醒。而wait()方法是Object类的方法,用于线程间的通信,这个方法会使当前拥有该对象锁的进程等待,直到其他线程用调用notify()或notifyAll()时才苏醒过来,开发人员也可以给它指定一个时间使其自动醒来。

2)对锁的处理机制不同。

  由于sleep()方法的主要作用是让线程暂停一段时间,时间一到则自动恢复,不涉及线程间的通信,因此调用sleep()方法仅仅释放CPU资源或者让当前线程停止执行一段时间,但不会释放锁。而wait()方法则不同,当调用wait()方法后,线程会释放掉它所占用的锁,从而使线程所在对象中的其他synchronized数据可被别的线程使用。

3)使用区域不同。

wait()方法必须放在同步控制方法或者同步语句块中使用,而sleep方法则可以放在任何地方使用。sleep()方法必须捕获异常,而wait()、notify()、notifyAll()不需要捕获异常。在sleep的过程中,有可能被其他对象调用它的interrupt(),产生InterruptedException异常。

  由于sleep不会释放锁标志,容易导致死锁问题的发生,一般情况下,不推荐使用sleep()方法,而推荐使用wait()方法。

12. 有三个线程T1,T2,T3,怎么确保它们按顺序执行?

在多线程中有多种方法让线程按特定顺序执行,你可以用线程类的join()方法在一个线程中启动另一个线程,另外一个线程完成该线程继续执行。为了确保三个线程的顺序你应该先启动最后一个(T3调用T2,T2调用T1),这样T1就会先完成而T3最后完成。

13. 如何创建守护线程?

  使用Thread类的setDaemon(true)方法可以将线程设置为守护线程,需要注意的是,需要在调用start()方法前调用这个方法,否则会抛出IllegalThreadStateException异常。

/*** @author}

前提知识:

守护进程(Daemon)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件(百度百科)。

Java线程分为两类分别为daemon线程(守护线程)和User线程(用户线程),在JVM启动时候会调用main函数,main函数所在的线程是一个用户线程,这个是我们可以看到的线程,其实JVM内部同时还启动了好多守护线程,比如垃圾回收线程。那么守护线程和用户线程有什么区别那?区别之一是当最后一个非守护线程结束时候,JVM会正常退出,而不管当前是否有守护线程,也就是说守护线程是否结束并不影响JVM的退出。言外之意是只要有一个用户线程还没结束正常情况下JVM就不会退出。

14. 什么是线程调度器(Thread Scheduler)和时间分片(Time Slicing)?

  线程调度器是一个操作系统服务,它负责为Runnable状态的线程分配CPU时间。一旦我们创建一个线程并启动它,它的执行便依赖于线程调度器的实现。

  时间分片是指将可用的CPU时间分配给可用的Runnable线程的过程。分配CPU时间可以基于线程优先级或者线程等待的时间。线程调度并不受到Java虚拟机控制,所以由应用程序来控制它是更好的选择(即最好不要让你的程序依赖于线程的优先级)。

15.什么是ThreadLocal?

ThreadLocal用于创建线程的本地变量,我们知道一个对象的所有线程会共享它的全局变量,所以这些变量不是线程安全的,我们可以使用同步技术。但是当我们不想使用同步的时候,我们可以选择ThreadLocal变量。每个线程都会拥有他们自己的Thread变量,它们可以使用get()/set()方法去获取他们的默认值或者在线程内部改变他们的值。

16.Java线程池中submit() 和 execute()方法有什么区别?

两个方法都可以向线程池提交任务,execute()方法的返回类型是void,它定义在Executor接口中, 而submit()方法可以返回持有计算结果的Future对象,它定义在ExecutorService接口中,它扩展了Executor接口,其它线程池类像ThreadPoolExecutor和ScheduledThreadPoolExecutor都有这些方法。

17. Java中Runnable和Callable有什么不同?

Runnable和Callable都代表那些要在不同的线程中执行的任务。Runnable从JDK1.0开始就有了,Callable是在JDK1.5增加的。它们的主要区别是Callable的 call() 方法可以返回任务执行结果值和抛出异常,而Runnable的run()方法没有这些功能。Callable可以返回装载有计算结果的Future对象。

高并发

1. 什么是FutureTask?

在Java并发程序中FutureTask表示一个可以取消的异步运算。它有启动和取消运算、查询运算是否完成和取回运算结果等方法。只有当运算完成的时候结果才能取回,如果运算尚未完成get方法将会阻塞。一个FutureTask对象可以对调用了Callable和Runnable的对象进行包装,由于FutureTask也是调用了Runnable接口所以它可以提交给Executor来执行。



标签:调用,Java,Object,接口,线程,动态创建,sleep,方法
From: https://blog.51cto.com/u_4018548/6430473

相关文章

  • java.lang.OutOfMemoryError:GC overhead limit exceeded异常
    java.lang.OutOfMemoryError异常解决方法 原因:常见的有以下几种:1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据;2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;3.代码中存在死循环或循环产生过多重复的对象实体;4.使用的第三方软件中的BUG;5.启动参数内存......
  • 四川省重点用能单位能耗在线监测系统平台接口协议
    本部分是对国家规范中《重点用能单位能耗在线监测系统-基础信息与格式规范》《重点用能单位能耗在线监测系统-端设备接口协议规范》这两个协议规范文档的补充本部分适用于四川省重点用能单位能耗在线监测系统平台应用软件、接口协议应用、能耗监测端设备开发等,实际执行以国家标准......
  • JAVA基础知识总结系列:JAVA封装
    封装(面向对象特征之一):是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。好处:将变化隔离;便于使用;提高重用性;安全性。封装原则:将不需要对外提供的内容都隐藏起来,把属性都隐藏,提供公共方法对其访问。this:代表对象。就是所在函数所属对象的引用。this到底代表什么呢?哪个对象......
  • 循环中调用异步接口获取数据
      //查询人员列表  asyncgetPersonList(){   const_this=this;   constdata=awaitgetPersonList(this.formSearch);   console.log("data",data);   varpromiseList=[];   data.forEach((element,inds)=>{   ......
  • JavaScript上传文件
    效果实现无论是上传文件还是上传图片,用的都是input标签的type="file";input标签触发onChange事件时,会接受input元素本身作为参数,元素对象的files属性,值是fileList(即文件列表,列表中是一个个文件对象,文件对象包括文件的名称,大小等);有了文件列表之后,需要创建一个FileReader对象......
  • 机器学习入门-用Java实现简单感知机
    一、通俗理解机器学习1、机器学习是人工智能的一种,如图所示,它是人工智能的一个子方向。2、机器学习有点像人类的学习过程。1.人类学习通过经验(事件),归纳出规律。2.机器学习通过数据,训练出模型。3、机器学习不是基于编程形成的直接结果,不是代码直接写出一个模型y=-0.......
  • Java中使用POI读取大的Excel文件或者输入流时发生out of memory异常参考解决方案
     使用ExcelStreamingReader,这个第三方工具会把一部分的行(可以设置)缓存到内存中,在迭代时不断加载行到内存中,而不是一次性的加载所有记录到内存,这样就可以不断的读取excel内容并且不影响内存的使用。  但是这个工具也有一定的限制:只能用于读取excel的内容,写入操作不可用;可以使......
  • 基于JAVA知识管理系统的设计和实现
    系统功能系统分为网站前台和网站后台,前台主要为查阅文档功能、评分等,后台主要进行文档管理功能等。网站前所示台功能包括用户注册、登录、文档显示、搜索文档、浏览文档和评论文档。(1)注册在注册页面填写注册信息,要求填写用户名(汉字、字母、数字或下划线组成的字符串,且不能有重......
  • Java动态绑定机制
    Java的动态绑定机制当调用对象方法的时候,该方法会和该对象的内存地址\运行类型绑定当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用packagehspedu.poly_.dynamic_;publicclassDynamicBinding{publicstaticvoidmain(String[]args){Aa=newB(......
  • 2.3. 接口与抽象类
    接口和抽象类是Java中两种实现抽象和多态的方法。它们之间有一些区别,但也有一些相似之处。这一节我们将通过详细的例子来更深入地了解接口和抽象类。2.3.1.接口接口可以定义一组方法签名,但不能包含方法的实现。一个类可以实现多个接口,实现接口的类必须实现接口中定义的所有方......