JavaSE第五周复习需要注意的知识点

Callable

定义:public interface Callable

JDK1.5之后出现,与Runnable接口类似,实现之后代表一个线程任务

Callable具有泛型返回值,可以声明异常

方法:public V call() throws Exception
相当于Runnable接口中的run()方法,但是有返回值

如何开启start方法:
1)FutureTask类继承自Runnable,并有构造参数可以接收Callable接口的实现类对象,在通过Thread接收Runnable实现类对象的构造方法,启动start()。
FutureTask同时继承Future方法,继承的get()方法可以获得Callable的call()方法的返回值。

2)通过线程池提交线程任务来实现Callable多线程
在这里插入图片描述

public class CallableDemo {
	public static void main(String[] args) throws Exception {
		//1、创建Callable对象
		Callable<Integer> callable = new Callable<Integer>() {

			@Override
			public Integer call() throws Exception {
				System.out.println(Thread.currentThread().getName() + "开始计算");
				int sum = 0;
				for(int i = 0 ; i < 100 ; i++) {
					sum+= i ;
				}
				return sum;
			}			
		};
		
		//把callable对象转成可执行的任务
		FutureTask<Integer> ft = new FutureTask<Integer>(callable);
		
		//Thread
		new Thread(ft).start();
		
		//接收返回值FutureTask.get(),等待call方法执行完毕,才会返回
		Integer sum = ft.get();
		System.out.println(sum);
		
	}
}

线程池

定义:线程池可以理解为是一个线程容器,可设定线程分配的数量上限。

作用:将预先创建的线程对象存入池中,并重用线程池中的线程对象,避免频繁的创建和销毁线程,占用资源。

常用的线程池接口和类
都在java.util.concurrent包中

1)Executor:线程池的顶级接口
定义:public interface Executor
方法:public void execute(Runnable command)

2)ExecutorService:线程池接口
定义:public interface ExecutorService extends Executor
方法:public Future<?> submit(Runnable task)
public Future submit(Callable task)
//提交线程任务
3)Executors线程池工厂类(通过此类可以获得一个线程池)
定义:public class Executors extends Object
方法:
创建固定数量的线程池:public static ExecutorService newFixedThreadPool(int nThreads)//参数为线程池中的线程数量
获得动态数量的线程池:public static ExecutorService newCachedThreadPool()
创建单线程池:public static ExecutorService newSingleThreadExecutor()
创建调度线程池:public static ExecutorService newScheduledThreadPool(int corePoolSize)

在这里插入图片描述

public class ThreadPool {
	public static void main(String[] args) {
		//1、创建固定线程个数的线程池
		//ExecutorService es = Executors.newFixedThreadPool(4);
		
		//2、创建缓存线程池:线程个数由提交的任务决定
		ExecutorService es = Executors.newCachedThreadPool();
		
		//3、创建单线程池:里面只有一个线程
		//ExecutorService es = Executors.newSingleThreadExecutor();
		
		//4、创建调度线程池,调度:周期,定时执行
		//ExecutorService es = Executors.newScheduledThreadPool(4);
		
		//创建任务
		Runnable runnable = new Runnable() {
			private int ticket = 100;
			@Override
			public void run() {
				while(true) {
					if(ticket <= 0) {
					break;
				}
					System.out.println(Thread.currentThread().getName() + "第" + ticket-- + "票");
				}
			
			}
		};
		
		//提交任务
		for(int i = 0 ; i < 5 ; i++) {
			Future<?> ft = es.submit(runnable);
			System.out.println(ft);
		}
		
		//关闭线程池
		es.shutdown();//等待任务执行完毕
		es.shutdownNow();//立即关闭不等待任务完成
	}
}

ExecutorService提交线程任务的方法的返回值为Future<?>,Future接口具有get()方法,可以获取线程的返回值,返回值可以通过Callable接口的call方法实现。

方法:public Future submit(Callable task)

//使用两个线程,并发计算1-50,51-100的和,在进行汇总
public class FutureDemo {
	public static void main(String[] args) throws Exception{
		ExecutorService es = Executors.newFixedThreadPool(2);
		Future<Integer> result1 = es.submit(new Callable<Integer>(){

			public Integer call() throws Exception {
				System.out.println(Thread.currentThread().getName() + "开始计算1-50");
				int sum = 0;
				for(int i = 1 ; i <= 50 ; i++) {
					sum += i;
				}
				return sum;
			}
		});
		
		Future<Integer> result2 = es.submit(new Callable<Integer>() {
			@Override
			public Integer call() throws Exception {
				System.out.println(Thread.currentThread().getName() + "开始计算51-100");
				int sum = 0;
				for(int i = 51 ; i <= 100 ; i++) {
					sum += i;
				}
				return sum;
			}
		});
		
		int res = result1.get() + result2.get();
		System.out.printf("结果为%d + %d = %d", result1.get(), result2.get(), res);
		
		es.shutdown();
	}
}

/*运行结果
pool-1-thread-1开始计算1-50
pool-1-thread-2开始计算51-100
结果为1275 + 3775 = 5050
*/

注解(Annotation)

从jdk1.5开始,不是程序本身,可以对程序作出解释,可以被其他程序(编译器等)读取。

格式
注解以@注释名在代码中存在,还可以添加一些参数值

使用
可以附加在package,class,method,field等上面,相当于给他们添加了额外的辅助信息

内置注解
@Override:定义在java.lang.Override中,此注释只适用于修辞方法,表示一个方法生命打算重写超类中的另一个方法声明
@Deprecated:定义在java.lang.Deprecated中,此注释可以用于修辞方法,属性,类,表示不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择
@SuppressWarnings:定义在java.lang.SuppressWamings中,用来抑制编译时的警告信息
与前两个不同,需要添加参数
@SuppressWarnings(“all”)
@SuppressWarnings(“unchecked”)
@SuppressWarnings(value={“unchecked”,“deprecation”})等

元注解
作用是负责注解其他注解,java定义了4个校准的meta-annotation类型,他们被用来提供对其他annotation类型做说明
这些类型和它们所支持的类在java.lang.annotation包中可以找到(@Target,@Retention,@Documented,@Inhrited)

@Target:用于描述注解的适用范围(即注解可以用在什么地方)
@Retention:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(SOURCE < CLASS < RUNTIME)
@Document:说明该注解将被包含在javadoc中
@Inherited:说明子类可以继承父类中的该注解

自定义注解
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口

1)@interface用来声明一个注解,public @interface 注解名{自定义内容}
2)其中的每一个方法实际上是声明了一个配置参数
3)方法的名称就是参数的名称
4)返回值类型就是参数的类型(返回值只能是基本类型Class,String,enum)
5)可以用过default来声明参数的默认值
6)如果只有一个参数成员,一般参数名value
7)注解元素必须要有值,我们定义注解元素时,经常使用空字符串0作为默认值

@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
	//注解的参数:参数类型 + 参数名();
	String name() default "";
	int age () default 0;
	int id() default -1;//如果默认值为-1,代表不存在
	
	String[] schools();
}

@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2{
	//只有一个参数最好写value
	String value();
}

public class AnnatationDemo {
	//注解可以显示赋值,如果没有默认值则必须给注解赋值
	@MyAnnotation(name = "秦酱",schools = {"西北大学"})
	public void test() {};
	
	//只有一个值,且参数名为value,可以省略参数名 = 
	@MyAnnotation2("X")
	public void test2() {};
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值