day18

来源:互联网 发布:淘宝贷利息多少 编辑:程序博客网 时间:2024/04/30 22:26
一、反射               
1、获取方法和属性 
   反射可以获取这个类中定义的方法和属性的信息,简单数据类型在使用反射时要转换成封装类。 
   Class c = Teacher.class; 
   Method m = c.getMethod("mrthod",int.class); 
   
2、通过类对象生成类的对象 
   Class c = Teacher.class; 
   Object o = c.newInstance(); 

3、通过类对象调用方法   
   //1.get class Object 
   Class c=Class.forName("Student"); 
   //2.get Constructor object 
   Class[] cs={String.class}; 
   Constructor con=c.getConstructor(cs);//按照参数表来调用制定构造方法。 
   //3.create object 
   Object[] os={"liucy"}; 
   Object o=con.newInstance(os); 
   //4.get method object 
   String methodName="study"; 
   Class[] pcs={String.class}; 
   Method m=c.getMethod(methodName,pcs);//按照参数表来获得制定的方法对象。 
   //5.invoke the method 
   Object[] ocs={"EJB"}; 
   m.invoke(o,ocs); 
   
   
二、CoreJava 5.0的注释 
1、定义:Annotation描述代码的代码(区:描述代码的文字) 
             给机器看         给人看的 
2、注释的分类: 
(1)、标记注释:没有任何属性的注释。@注释名 
(2)、单值注释:只有一个属性的注释。@注释名(value=___) 
在单值注释中如果只有一个属性且属性名就是value,则“value=”可以省略。 
(3)、多值注释:有多个属性的注释。多值注释又叫普通注释。 
@注释名(多个属性附值,中间用逗号隔开) 
3、内置注释: 
(1)、Override(只能用来注释方法) 
表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。 
(2)、Deprecated 
用 @Deprecated 注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。 
(3)、SuppressWarnings(该注释无效) 
指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告。 

4、自定义注释 
自定义注释 
    public  @interface Test{ 
    
    } 
    在自定义注释时,要用注释来注释(描述)注释。 
    @target(),用来描述(注释)注释所能够注释的程序员元素。 
    @Retention(),描述(注释)注释要保留多久。 
    注释的属性类型可以是 
    8种基本类型 
    String 
    Enum 
    Annotation 
    以及它们的数组 

5、注释的注释:java.lang. annotation包中 
(1)、Target:指示注释类型所适用的程序元素的种类。 
例:@Target(value = {ElementType.METHOD}); 
说明该注释用来修饰方法。 
(2)、Retention:指示注释类型的注释要保留多久。如果注释类型声明中不存在 Retention 注释,则保留策略默认为 RetentionPolicy.CLASS。 
例:Retention(value = {RetentionPolicy.xxx} 
    当x为CLASS表示保留到类文件中,运行时抛弃。 
   当x为RUNTIME表示运行时仍保留 
   当x为SOURCE时表示编译后丢弃。 
(3)、Documented:指示某一类型的注释将通过 javadoc 和类似的默认工具进行文档化。应使用此类型来注释这些类型的声明:其注释会影响由其客户端注释的元素的使用。 
(4)、Inherited:指示注释类型被自动继承。如果在注释类型声 
明中存在 Inherited 元注释,并且用户在某一类声明中查询该注释类型,同时该类声明中没有此类型的注释,则将在该类的超类中自动查询该注释类型。 
注:在注释中,一个属性既是属性又是方法。 

■ 标注:描述代码的文字 
    描述代码的代码。给编译器看的代码,作用是规范编译器的语法。 
    class Student{ 
      @Override 
      public String toString(){ 
        return “student”; 
      } 
    
    } 
  ■ 注释类型 java.lang 
    1、标记注释(没有属性) 
      @Override 
    2、单值注释 
      @注释名(a="liucy") 
      @注释名(prameter=10) 
      int parameter 
      特例: 
      @注释名 (value=“134” ) 
      等价于 @注释名 (“134” ) 
    3.普通注释(多值注释) 
    (key1=value,……) 
      @__(a="liucy,b=10) 

  ■ @Override 只能放在方法前面 
    @Deprecated 用于描述过期 
    @SuppressWarnings 抑制警告 
          @SuperessWarning({“ddd”,”aaa”,”ccc”})  //JVM还没有实现这个注释
           

三、Java5.0中的并发 
1、所在的包:Java.util.concurrent 
2、重写线程的原因: 
(1)何一个进程的创建(连接)和销毁(释放资源)的过程都          是一个不可忽视的开销。 
(2)run方法的缺陷:没有返回值,没有抛例外。 
3、对比1.4和5.0的线程 

       5.0           1.4 
ExecutorService        取代 Thread 
Callable   Future      取代 Runnable 
Lock                取代 Synchronized 
SignalAll        取代 notifyAll() 
await()                取代 wait() 


    三个新加的多线程包 
    
    Java 5.0里新加入了三个多线程包:java.util.concurrent, java.util.concurrent.atomic, 
    
    java.util.concurrent.locks. 
    java.util.concurrent包含了常用的多线程工具,是新的多线程工具的主体。 
    java.util.concurrent.atomic包含了不用加锁情况下就能改变值的原子变量,比如说AtomicInteger提供了addAndGet()方法。Add和Get是两个不同的操作,为了保证别的线程不干扰,以往的做法是先锁定共享的变量,然后在锁定的范围内进行两步操作。但用AtomicInteger.addAndGet()就不用担心锁定的事了,其内部实现保证了这两步操作是在原子量级发生的,不会被别的线程干扰。 
    java.util.concurrent.locks包包含锁定的工具。 
    
    Callable 和 Future接口 
    
    Executor接口替代了Thread类,他可以创建定量的和动态以及周期性的线程池。 
    ExecutorService接口,线程池,用来存放线程来节省创建和销毁资源的消耗。 
    
    Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。Callable和Runnable有几点不同: 
    Callable规定的方法是call(),而Runnable规定的方法是run(). 
    Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。 
    call()方法可抛出异常,而run()方法是不能抛出异常的。 
     
    Future对象可以获得线程运行的返回值 
    
    运行Callable任务可拿到一个Future对象,通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。 
    以下是Callable的一个例子: 
    public class DoCallStuff implements Callable{ // *1 
            private int aInt; 
            public DoCallStuff(int aInt) { 
                    this.aInt = aInt; 
            } 
            public String call() throws Exception { //*2 
                    boolean resultOk = false; 
                    if(aInt == 0){ 
                            resultOk = true; 
                    }  else if(aInt == 1){ 
                            while(true){ //infinite loop 
                                    System.out.println("looping...."); 
                                    Thread.sleep(3000); 
                            } 
                    } else { 
                            throw new Exception("Callable terminated with Exception!"); //*3 
                    } 
                    if(resultOk){ 
                            return "Task done."; 
                    } else { 
                            return "Task failed"; 
                    } 
            } 
    } 
    *1: 名为DoCallStuff类实现了Callable,String将是call方法的返回值类型。例子中用了String,但可以是任何Java类。 
    *2: call方法的返回值类型为String,这是和类的定义相对应的。并且可以抛出异常。 
    *3: call方法可以抛出异常,如加重的斜体字所示。 
    以下是调用DoCallStuff的主程序。 
    import java.util.concurrent.ExecutionException; 
    import java.util.concurrent.ExecutorService; 
    import java.util.concurrent.Executors; 
    import java.util.concurrent.Future; 
    public class Executor { 
            public static void main(String[] args){ 
                    //*1 
                    DoCallStuff call1 = new DoCallStuff(0); 
                    DoCallStuff call2 = new DoCallStuff(1); 
                    DoCallStuff call3 = new DoCallStuff(2); 
                    //*2 
                    ExecutorService es = Executors.newFixedThreadPool(3); 
                    //*3 
                    Future future1 = es.submit(call1); 
                    Future future2 = es.submit(call2); 
                    Future future3 = es.submit(call3); 
                    try { 
                            //*4 
                            System.out.println(future1.get()); 
                             //*5 
                            Thread.sleep(3000); 
                            System.out.println("Thread 2 terminated? :" + future2.cancel(true)); 
                            //*6 
                            System.out.println(future3.get()); 
                    } catch (ExecutionException ex) { 
                            ex.printStackTrace(); 
                    } catch (InterruptedException ex) { 
                            ex.printStackTrace(); 
                    } 
            } 
    } 
    *1: 定义了几个任务 
    *2: 初始了任务执行工具。任务的执行框架将会在后面解释。 
    *3: 执行任务,任务启动时返回了一个Future对象,如果想得到任务执行的结果或者是异常可对这个Future对象进行操作。Future所含的值必须跟Callable所含的值对映,比如说例子中Future对印Callable 
    *4: 任务1正常执行完毕,future1.get()会返回线程的值 
    *5: 任务2在进行一个死循环,调用future2.cancel(true)来中止此线程。传入的参数标明是否可打断线程,true表明可以打断。 
    *6: 任务3抛出异常,调用future3.get()时会引起异常的抛出。 
     运行Executor会有以下运行结果: 
    looping.... 
    Task done. //*1 
    looping.... 
    looping....//*2 
    looping.... 
    looping.... 
    looping.... 
    looping.... 
    Thread 2 terminated? :true //*3 
    //*4 
    java.util.concurrent.ExecutionException: java.lang.Exception: Callable terminated with Exception! 
            at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:205) 
            at java.util.concurrent.FutureTask.get(FutureTask.java:80) 
            at concurrent.Executor.main(Executor.java:43) 
            ……. 
    *1: 任务1正常结束 
    *2: 任务2是个死循环,这是它的打印结果 
    *3: 指示任务2被取消 
    *4: 在执行future3.get()时得到任务3抛出的异常 
    
    lock接口 
    
    实现类ReentrantLock 
     
    我们可以用lock对象,来对临界资源加锁,只有获得lock对象才能访问临界资源,如果没有获得lock对象,就会进入lock对象的锁池。trylock()方法会返回布尔值,这个方法是用来判断这个锁对象是不是已经被线程获取,如果返回值为true,则会直接获得这个锁对象,如果返回false,线程不会阻塞还会继续运行。 
    Lock lock=new ReentrantLock(); 
    publci void test(){ 
       try{ 
      lock.lock();//加锁 
      .....//需要加锁的临界资源。 
      }finally{ 
        lock.unlock();//解锁。 
      } 
    } 
    
    ReadWriteLock读写锁接口 
    
    ReentrantReadWriteLock是ReadWriteLock的实现类。 
    
    readLock()分配读锁,读锁可以分配多个线程,但是在分配读锁后所有读锁释放前,写锁时不能分配的。 
    Lock writeLock() 写锁只能分配给一个线程,在分配写锁后写锁是放前,读锁不能被分配。 
     
    Condition接口和实现类 
    
    await()替代了wait()方法。 
    notify(),notifyAll() 在JDK5.0中已经用signal() ,signalAll()方法替换掉了,在JDK5.0中,可以使用多个等待队来存放等待的线程,并对线程进行分类。 
     
    Queue接口(Collection的子接口,对列接口) 
    
    LinkedList也实现了这个在JDK5.0中的新接口Queue,并且这个类自动的实现了生产者和消费者的同步。 
    
    
    JDK5.0的高级同步 
    Semaphore类(信号量)也就是可以向线程分配许可证,指定许可证数量可以实现多线程的同步。 
    Semaphore s=new Semaphore(4);//可以分配4个许可证,许可证都被分配出去时,得不到许可证的线程就会阻塞。 
    
    acquire()方法,获得许可证。release() 方法,释放一个许可证,也有相应的方法指定释放和获得许可证的数量的方法。 
    
    CountDownLatch类, 
    
    CountDownLatch中有个计数器,访问这个类的对象就会从计数器中减一,countDown()方法会将原有的设置的计数器值减一,当countdown计数器为零时会使放所有await()的线程。 
    
    CyclicBarrier类 
    
    CyclicBarrier和CountDownLatch比较相似 
    CyclicBarrier在构造时给出线程数,只有等待的线程数到了构造方法中指定的数量,当最后一个线程等待后,所有的线程都会被释放,这个类是一个多线程汇合的工具。 
    
    Exchanger类,用exchange()方法可以使两个线程间相互交换对象,在两线程的同步点,等待第二个线程。在同步点时,交换对象,并同时被释放。  
原创粉丝点击