`
tzq668766
  • 浏览: 81592 次
  • 性别: Icon_minigender_1
  • 来自: 沈阳
社区版块
存档分类
最新评论

CoreJava学习心得17

阅读更多
JAVA5.0 的注释 (Annotation)

描述代码的代码。给编译器看的代码,作用是规范编译器的语法。
class Student{
	@Override
	public String toString(){
		return “student”;
	}

}

类型(接口)
1. 标记注释
标记注释中没有属性,所以也不需要为属性赋值
@Override

2. 单值注释
单值注释中只能定义一个属性。
@注释名(prameter=10)
int parameter

特例:
@注释名 (value “134” )(当单值注释的属性名为value时,可以省略属性名,直接写值)

@SuperessWarning({“ddd”,”aaa”,”ccc”})  //JVM还没有实现这个注释

3.普通注释(多值注释)
(key1=value,……)

4.自定义注释
public  @interface Test{

}

在自定义注释时,要用注释来注释(描述)注释。
@Target(value={……}),用来描述自定义注释所适用的程序元素的种类。单值注释
这个注释的值只能是ElementType枚举值,只能使用以下的值
ANNOTATION_TYPE 注释类型声明
CONSTRUCTOR 构造方法声明
FIELD 属性声明(包括枚举常量)
LOCAL_VARIABLE 局部变量声明
METHOD 方法声明 (常用)
PACKAGE 包声明
PARAMETER 参数声明
TYPE 类、接口(包括注释类型)或枚举声明(常用)
例:
@Target({ElementType.METHOD, ElementType .TYPE})//表示这个注释可用的范围,这个注释可以用在方法和类型及接口。

@Retention(value=……),描述(注释)注释能够保留到什么时候。单值注释
其中的值只能是以下的RetentionPolicy枚举的值
CLASS 编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释。
RUNTIME  编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。
SOURCE 编译器要丢弃的注释。
例:
@Retention(RetentionPolicy.RUNTIME)
// 编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。

@Documented表示某一类型的注释将通过 javadoc 和类似的默认工具进行文档化

@Inherited 表示注释类型该注释会被自动继承

注释的属性类型可以是8种基本类型、String、Enum、Class、Annotation以及它们的数组

例:
@Test()
public class MyClass2 {
	@Test()
	public void study(String name){
		System.out.println("Study "+name);
	}
	
	@Test(value="Meal")//单值注释
	@Author(value={@Name(firstName="Liu",lastName="Chunyang"),@Name(firstName="Xue",lastName="Hiloo")})//单值注释中是用数组类型地赋值方法
	public void eat(String food){
		System.out.println("Eat "+food);
	}
}


自定义注释的写法
例:
import java.lang.annotation.*;
@Target({ElementType.METHOD})
//表示这个注释可用的范围,这个注释只能用在方法之上。
@Retention(RetentionPolicy.RUNTIME)
// 编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。public @interface Author {
	Name[] value();
/*
定义注释的属性,注意属性后面要价括号,这个属性既是属性又是方法,可以返回属性的值
*/
}

import java.lang.annotation.*;
@Target({ElementType.METHOD,ElementType.TYPE})//这个注释可用于类,接口和方法
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
	String value() default "ABC" ;//定义注释的属性及其默认值
}

处理自定义注释的类
例:
import java.lang.reflect.*;
public class TestFramework {
	public static void main(String[] args) throws Exception {
		Class c=Class.forName("MyClass2");//获取有注释的类的类对象
		Method[] ms=c.getMethods();//获得该类中有的方法对象
		Object o=c.newInstance();//获得该类的实例
		for(Method m:ms){
			boolean flag=m.isAnnotationPresent(Test.class);
/*
isAnnotationPresent(Class c)这个方法是判断这个方法是不是加上了注释注意这是方法对象的方法
*/
			if (flag){
				Test t=m.getAnnotation(Test.class);
/*
getAnnotation(Class c)方法是获得该方法的注释,得到注释对象t
可以通过注释对象 ”属性名()”也就是value(),获得注释的属性的值
*/
				String value=t.value();
				m.invoke(o,value);
			}
			
			flag=m.isAnnotationPresent(Author.class);
			if (flag){
				Author a=m.getAnnotation(Author.class);
				Name[] ns=a.value();
				for(Name n:ns){
					String fn=n.firstName();
					String ln=n.lastName();
					System.out.println(fn+ "  "+ ln);
				}
			}
		}
		
	}

}


例2:
定义注释
import java.lang.annotation.*;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
	String name();
	String sex();
}

使用注释
public class TestAnntion {
	@Test(name="liucy",sex="man")
	public void test(String name,String sex){
		System.out.println(name+" "+sex);
	}
}

处理注释

import java.lang.reflect.Method;
public class TestT {

	public static void main(String[] args) throws Exception {
		Class c=Class.forName(args[0]);
		Method[] ms=c.getMethods();
Object o=c.newInstance();
for(Method m:ms){
			boolean flag=m.isAnnotationPresent(Test.class);
			if (flag){
				Test t=m.getAnnotation(Test.class);
				String name=t.name();
				String sex=t.sex();
				m.invoke(o, name,sex);
			}		
	}

}


三个新加的多线程包

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对象的unlock()方法,并且释放锁,只有获得lock对象才能访问临界资源,如果没有获得lock对象,就会进入lock对象的锁池。trylock()方法会返回布尔值,这个方法是用来判断这个锁对象是不是已经被线程获取,如果返回值为true,则会直接获得这个锁对象,如果返回false,线程不会阻塞还会继续运行。
Lock lock=new ReentrantLock();
publci void test(){
   try{
if(lock.trylock){//判断锁是否已经分配出去
lock.lock();
//如果锁没有被分配,就会获得锁,没有得到锁,就阻塞
}else{
......
}
.....//需要加锁的临界资源。
}finally{
lock.unlock();//解锁,释放锁。
}
}

ReadWriteLock读写锁接口

ReentrantReadWriteLock是ReadWriteLock的实现类。

ReentrantReadWriteLock的Lock  readLock()方法会分配读锁对象,读锁可以分配多个线程,但是在分配读锁后所有读锁释放前,写锁是不能被分配的。
ReentrantReadWriteLock的Lock  writeLock()方法会分配写锁对象,且只能分配给一个线程,在分配写锁后,在写锁释放前,读锁是不能被分配。

Condition接口和实现类

Condition是等待对列的对象,它是通过lock对象的newCondition()方法得到的
Condition实现类的await()替代了wait()方法。
notify(),notifyAll() 在JDK5.0中已经用Condition实现类的signal() ,signalAll()方法替换掉了,在JDK5.0中,可以使用多个等待队来存放等待的线程,并对线程进行分类。

Queue接口(Collection的子接口,队列接口)

LinkedList也实现了这个在JDK5.0中的新接口Queue,并且这个类自动的实现了生产者和消费者的同步。


JDK5.0的高级同步

Semaphore类(信号量)也就是可以向线程分配许可证,指定许可证数量可以实现多线程的同步。
Semaphore s=new Semaphore(4);
//可以分配4个许可证,许可证都被分配出去时,得不到许可证的线程就会阻塞。

Semaphore类的acquire(…)方法,获得许可证。Semaphore类的release(…) 方法,释放一个许可证,也有相应的方法指定释放和获得许可证的数量的方法。

CountDownLatch类

CountDownLatch中有个计数器,访问这个类的对象就会从计数器中减一,countDown()方法会将原有的设置的计数器值减一,当countdown计数器为零时会使放所有await()的线程。

CyclicBarrier类

CyclicBarrier和CountDownLatch比较相似
CyclicBarrier在构造时给出线程数,只有等待的线程数到了构造方法中指定的数量,当最后一个线程等待后,所有的线程都会被释放,这个类是一个多线程汇合的工具。

Exchanger类,用exchange()方法可以使两个线程间相互交换对象,在两线程的同步点,等待第二个线程。在同步点时,交换对象,并同时被释放。
分享到:
评论

相关推荐

    Core Java 学习笔记

    《Core Java》学习笔记。 我把自己的笔记都以注释的形式写在代码里面了,这样方便理解。 尽管有些部分被标记为“已完成”,但实际上以后说不定我还会折返回来进行修改或者添加一些注释。 当然如果你有什么不理解...

    CoreJava卷一学习笔记

    自己学习corejava核心技术卷一时的学习笔记和心得,提出的一些问题

    corejava练习题目(1)

    综上所述,"CoreJava练习题目(1)"是一个非常实用的Java学习资源。它通过一系列贴近实际应用的编程习题,帮助学习者将理论知识转化为实践技能,提升自身的编程能力。无论是编程初学者还是希望进一步提升技术的开发者...

    Java学习笔记及心得

    ### Java学习笔记及心得知识点详细解析 #### 标题:Java学习笔记及心得 #### 描述:Core Java 学习笔记及心得 pdf格式可打开。涵盖了java的基础入门知识,非常适合自学的及想深入学习理解的同学。 #### 标签:...

    Core Java心得笔记

    【Core Java心得笔记】主要涵盖了Java编程的基础及进阶知识,包括对象导向编程、类与对象、封装、继承、多态、接口、异常处理、集合框架、IO流、线程等核心概念。以下是对这些知识点的详细阐述: 1. **对象导向编程...

    Corejava 核心java笔记

    这份名为"Corejava 核心java笔记"的资料应该包含了作者在学习Java基础时的一些理解和实践心得,对于初学者来说是一份宝贵的参考资料。 1. **Java语法**: Java语法简洁而严谨,包括变量声明、数据类型(如整型、浮点...

    UNIX、Oracle、CoreJava语言基础实训心得.pdf

    "UNIX、Oracle、CoreJava语言基础实训心得.pdf" 本文档主要介绍了UNIX、Oracle和Core Java语言基础实训的知识点,涵盖了宽带运营支撑系统、UNIX基本命令、Oracle数据库SQL命令、Java语言的基本概念等方面。 一、...

    UNIX、Oracle、CoreJava语言基础实训心得.docx

    在本次的实训中,主要涉及了三个核心领域:UNIX操作系统、Oracle数据库管理和Core Java编程语言。以下是关于这些领域的详细知识: 1. **UNIX操作系统**: - **WOSS系统**:Wide-Brand Operation Support System是...

    UNIX、Oracle、Core Java 语言基础实训心得.doc

    在本次“UNIX、Oracle、Core Java 语言基础实训”中,我深入学习了这三个关键领域的基础知识,并且在实践中积累了丰富的经验。UNIX系统是广泛应用于服务器环境的操作系统,其稳定性和高效性是其核心优势。在实训过程...

    C# 学习心得(最新)

    作为.NET框架的重要组成部分,C#结合了C++的强类型系统和Java的简洁性,提供了一种高效、安全且现代的编程环境。 在学习C#的过程中,有几个核心知识点是必不可少的: 1. **基础语法**:C#的基础语法包括变量声明、...

    C# 自学学习心得

    本文将基于"C#自学学习心得"的标题和描述,详细探讨C#中的WinForm和WebForm开发,以及相关的学习经验。 首先,让我们从C#的基础开始。C#是由微软公司开发的一种面向对象的语言,它具有简洁、类型安全和性能高效的...

    Spring学习心得(一)

    在Spring框架的学习过程中,我们可以深入理解到它在Java企业级应用中的核心作用。Spring作为一个开源的、全面的企业级应用开发框架,它简化了Java EE(Enterprise Edition)开发,提供了丰富的功能,包括依赖注入...

    [计算机]JAVA入门书籍读后感.doc

    【描述】:这份读后感来源于一篇《电子商务基础》课程的大作业,作者蒋凤娇在指导教师张文胜的指导下,于2011年6月完成了对JAVA入门书籍《Core Java》的学习心得。 【标签】:“文档资料” 【正文】: 《Core ...

    java笔记图解11

    总的来说,这份"Java笔记图解11"资料涵盖了从基础到进阶的Java编程知识,从集合框架到框架使用,再到Map接口的深入学习,以及个人学习心得和核心技术的详细研究。通过这些内容的学习,可以系统提升Java编程技能,为...

    java核心技术

    Cay S.Horstmann等编著,公飞编译的《Java核心技术》(Core Java), 自第1版出版以来,一直备受广大Java程序设计人员的青睐,畅销不衰,是, Java经典书籍。第8版针对Java SE 6平台进行了全面更新,囊括了Java平, 台...

    Spring学习心得(二)——日志和数据库

    在本文中,我们将深入探讨这两个关键领域,并基于给出的"Spring学习心得(二)——日志和数据库"这个标题进行详细的阐述。 首先,让我们从日志开始。在Java应用程序中,日志系统扮演着调试、监控和问题排查的关键角色...

    Java 推荐读物与源代码阅读

    因此,在入门阶段可以选择Prentice Hall PTR的《Core Java 2》(国内称为《Java 2核心技术》),这本书更为适合初学者,目前已经有第七版,可以在网上找到电子版资源。另一本不错的选择是O'Reilly出版社的《Java in ...

Global site tag (gtag.js) - Google Analytics