ScheduledThreadPoolExecutor:可调度的线程池
public class ScheduledThreadPoolDemo { public static void main(String[] args) { ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);//线程池允许执行的线程数 scheduledExecutorService.scheduleAtFixedRate(new Runnable() { @Override public void run() { System.out.println("延迟1秒执行,每3秒执行一次"); } },1,3, TimeUnit.SECONDS); scheduledExecutorService.shutdown(); } }
public class ScheduledThreadPoolDemo { public static void main(String[] args) { ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);//线程池允许执行的线程数 scheduledExecutorService.schedule(new Runnable() { @Override public void run() { System.out.println("延迟5秒执行"); } },3, TimeUnit.SECONDS); scheduledExecutorService.shutdown(); } }
线程池的生命周期:
RUNNING :能接受新的任务,并且也能处理阻塞队列中的任务。
SHUTDOWN:关闭状态,不再接受新提交的任务,但却可以继续处理阻塞队列中的已保存的任务。
STOP:不能接受新任务,也不处理队列中的任务,会中断正在处理任务的线程。
TIDYING:如果所有的任务都已终止了,workCount(有效线程数)为0,线程池进入该状态后会调用terminated()方法进入TREMINATED状态。
TERMINATED:在terminated()方法执行完后进入该状态,默认terminated()方法中什么也没有做。
线程池参数:
corePoolSize:核心线程池的大小
maximumPoolSize:线程池能创建线程的最大个数
keepAliveTime:空闲线程存活时间
unit:时间单位,为keepAliveTime指定时间单位
workQueue:阻塞队列,用于保存任务的阻塞队列
threadFactory:创建线程的工厂类
handler:饱和策略(拒绝策略)
execute方法执行逻辑:
如果当前运行的线程少于corePoolSize,则会创建新的线程执行新的任务
如果运行的线程个数等于或者大于corePoolSize,则会将提交的任务存放到阻塞队列workQueue中;
如果当前workQueue队列已满的话,则会创建新的线程来执行任务;
如果线程个数已经超过了maximumPoolSize,则会使用饱和策略RejectedExecutionHandler来进行处理。
线程池的关闭:
关闭线程池,可以通过shutdown和shutdownNow两个方法
原理:遍历线程池中的所有线程,然后依次中断
shutdownNow首先将线程池的状态设置为STOP,然后尝试停止所有的正在执行和未执行任务的线程,并返回等待执行任务的列表。
shutdown只是将线程池的状态设置为SHUTDOWN状态,然后中断所有没有正在执行的线程。
网络编程:
两台主机之间通讯要先建立连接,建立连接要通过三次握手来建立,之后就会传输数据,最后要四次挥手断开连接。
public class InetAddressDemo { public static void main(String[] args) throws UnknownHostException { InetAddress localHost = InetAddress.getLocalHost();//获得本机主机IP地址 System.out.println(localHost); InetAddress byName = InetAddress.getByName("www.baidu.com"); InetAddress byName2 = InetAddress.getByName("WIN-AVA5NQL1LU5"); System.out.println(byName); } }
客户端:
public class Client { public static void main(String[] args) throws IOException { //创建socket对象,其实是开启实现io的虚拟接口 Socket client=new Socket("localhost",10086);//需要指定数据接收方的ip地址和端口号 //获取输出流对象,向服务端发送数据 OutputStream outputStream = client.getOutputStream(); //向输出流对象进行包装 DataOutputStream dataOutputStream = new DataOutputStream(outputStream); //传输数据 dataOutputStream.writeUTF("hello,你好,我是客户端"); //关闭流操作 dataOutputStream.close(); outputStream.close(); client.close(); } }
服务端:
public class Server { public static void main(String[] args) throws IOException { //服务端需要使用serversocket来开放本地的端口 ServerSocket serverSocket=new ServerSocket(10086); //需要接受client传输过来的数据,需要定义socket对象 Socket server=serverSocket.accept(); //通过server获取输入流对象 InputStream inputStream = server.getInputStream(); //对输入流进行包装 DataInputStream dataInputStream = new DataInputStream(inputStream); //读取对应的数据 String str=dataInputStream.readUTF(); System.out.println(str); //关闭所有的流操作 dataInputStream.close(); inputStream.close(); server.close(); serverSocket.close(); } }
JDK8新特性(Lambda表达式)
Lambda表达式介绍:
Lambda表达式是Java8中最重要的新功能之一。使用Lambda表达式可以替代只有一个抽象函数的接口实现,告别匿名内部类,代码看起来更简洁易懂。Lambda表达式同时还提升了对集合、框架的迭代、遍历、过滤数据的操作。
public class LambdaDemo { public static void main(String[] args) { Thread thread1=new Thread(new Runnable() { @Override public void run() { System.out.println("thread1 running..."); } }); thread1.start(); Thread thread2=new Thread(()-> System.out.println("thread2 running..")); thread2.start(); List<String> lists= Arrays.asList("java","javascript","scala","python"); Collections.sort(lists, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o1.length()-o2.length(); } }); for(String str:lists){ System.out.println(str); } Collections.sort(lists,(a,b)->(a.length()-b.length())); lists.forEach(System.out::println); } }
函数式接口:
public class LambdaDemo2 { public static void main(String[] args) { /** *在Java中提供了一系列的函数式接口,用来接受后续传入的逻辑,但是对输入和输出有要求 */ Function<String,Integer> f1=(str)->{return str.length();};//第一个参数是输入的参数,第二个是返回的数据 System.out.println(f1.apply("abcdefg")); Supplier<String> s1=()->{return "mashibing";}; Supplier<String> s2=()->"mashibing2"; System.out.println(s1.get()); System.out.println(s2.get()); } }
特点:
函数式编程
参数类型自动推断
代码量少、简洁
方法的引用:
静态方法引用:如果函数式接口的实现恰好可以通过调用一个静态方法来实现,那么就可以使用静态方法引用
public class Test2 { static String put(){ System.out.println("puting..."); return "put"; } public static void main(String[] args) { //静态方法引用 Supplier<String> s=Test2::put; System.out.println(s.get()); } }
实例方法引用:如果函数式接口的实现恰好可以通过调用一个实例的实例方法来实现,那么就可以使用实例方法引用
public class Test3 { public String put(){ return "put..."; } public static void main(String[] args) { Supplier<String> s=new Test3()::put ; System.out.println(s.get()); } }
- 对象方法引用:抽象方法的第一个参数类型刚好就是实例方法的类型,抽象方法剩余的参数可以恰好当做实例方法的参数。如果函数式接口的实现能由上面说的实例方法调用来实现的话,那么就可以使用对象方法引用
public class Test4 { public static void main(String[] args) { Consumer<Too> t1=Too::foo; t1.accept(new Too()); Consumer<Too2> t2=Too2::foo; t2.accept(new Too2()); } } class Too{ public Integer fun(String s){ return 1; } public void foo(){ System.out.println("foo"); } } class Too2{ public Integer fun(String s){ return 1; } public void foo(){ System.out.println("foo...."); } public void show(){ System.out.println("too...s"); } }
构造方法引用:如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现,那么就可以使用构造方法引用。
public class Test5 { public static void main(String[] args) { Supplier<Person> s2=Person::new; s2.get(); Supplier<List> s1= ArrayList::new; Function<String,Account> f1=(str)->new Account(str); Function<String,Account> f2=Account::new; f1.apply("abc"); f2.apply("def"); Consumer<Integer> c1=Account::new; c1.accept(3); } } class Account{ public Account(){ System.out.println("调用无参构造方法"); } public Account(int age){ System.out.println("age 参数方法调用"); } public Account(String str){ System.out.println("str 参数方法调用"); } } class Person{ public Person(){ System.out.println("无参构造方法调用"); } }