Java

Lambda表达式的线程安全问题与闭包

Submitted by Lizhe on Fri, 04/14/2017 - 11:07

 

Lambda表达式所使用的外部变量不能是可变的局部变量 (也就是说它只能接受成员变量,final的局部变量和参数)

下面例子中的test就是一个外部变量

实际上就是说,它不能接受非final的保存在线程祯中的变量, 等等, 这句话看起来是不是有点眼熟, 为什么会有这样的限制呢

首先这个Lambda表达式是运行在一个独立的子线程中,当这个线程运行时,它实际上拿到的是一个原始变量的副本(一个拷贝)

类似于经典的swap(a,b)函数,我相信每一个在大学学过c语言的人都碰到过这个考试题 :P

还记得Java8推出之前的热点问题么, java是否需要引入闭包, 那么Lambda表达式是否符合闭包的含义呢

闭包本身是一个函数,一段代码,一个可以被执行的逻辑, 它可以随意访问自身外部的其他变量,

Java8的Lambda表达式和匿名类也可以做类似于闭包的事情,比如下面这个例子里的Lambda表达式就访问了一个外部变量test

一般情况下很多人接触闭包都是通过javascript, javascript的闭包实际上是通过子函数来实现的,因为在javascript中只有一个函数的子函数才能访问这个函数的局部变量

Java8 stream reduce

Submitted by Lizhe on Thu, 04/13/2017 - 16:39

 

虽然上次我说filter方法有点类似于hadoop的Mapreduce,不过实际上stream提供了一个自己的方法也叫 reduce

通常情况下这个方法接受两个参数, 一个初始值,一个Lambda表达式

下面是一个求和的例子

 int total = students.stream().map(Student::getScore).reduce(0,(a,b)->a+b);

上面这个等价于 Optional<Integer> sum = students.stream().map(Student::getScore).reduce(Integer::sum);

首先我们把Students的list用map方法取出score, 然后初始值设置成0, 第一个值是0+80=80, 第二个值是80+81=161... 以此类推

取乘积的话可以用         int product = students.stream().map(Student::getScore).reduce(1,(a,b)->a*b);

这个方法还有一个不需要提供初始值的版本

Java8 stream api

Submitted by Lizhe on Thu, 04/13/2017 - 12:16

实际上java8的stream指导思想几乎跟hadoop的Mapreduce如出一辙, 

都是基于一个数据流,然后做reduce,最后进行一次聚合的操作,这种模型完美的匹配了多线程

import static静态导入是JDK1.5中的新特性。一般我们导入一个类都用 import com.....ClassName;而静态导入是这样:import static com.....ClassName.*;这里的多了个static,还有就是类名ClassName后面多了个 .* ,意思是导入这个类里的静态方法。当然,也可以只导入某个静态方法,只要把 .* 换成静态方法名就行了。然后在这个类中,就可以直接用方法名调用静态方法,而不必用ClassName.方法名 的方式来调用

下面的例子如果想使用多线程只需要改成

List<Student> stus3 = students.parallelStream().filter(s->s.getScore()>90).collect(toList());

Lambda表达式

Submitted by Lizhe on Fri, 03/31/2017 - 16:21

 

在正式了解Lambda表达式之前我们先谈谈函数式接口

简单来说,函数式接口是只包含一个方法的接口。

比如Java标准库中的java.lang.Runnable和 java.util.Comparator都是典型的函数式接口。

java 8提供 @FunctionalInterface作为注解,这个注解是非必须的,只要接口符合函数式接口的标准(即只包含一个方法的接口),虚拟机会自动判断, 但 最好在接口上使用注解@FunctionalInterface进行声明,以免团队的其他人员错误地往接口中添加新的方法。

Java中的lambda无法单独出现,它需要一个函数式接口来盛放,lambda表达式方法体其实就是函数接口的实现.

先用Comparator接口写个例子

打开Comparator接口的源码可以看到如下内容, 这是一个函数式接口

@FunctionalInterface
public interface Comparator<T> {

....

}

 

然后我们通过Lambda表达式给它添加一个实现

Java Rest

Submitted by Lizhe on Mon, 09/12/2016 - 19:06

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Authenticator;
import java.net.InetAddress;
import java.net.PasswordAuthentication;
import java.net.URL;

public class Test {
  public static void main(String[] argv) throws Exception {
    Authenticator.setDefault(new MyAuthenticator());
    URL url = new URL("http://hostname:80/index.html");

selenium driver

Submitted by Lizhe on Thu, 05/26/2016 - 16:35

    public static WebDriver createChromeDriver(){    
        System.setProperty("webdriver.chrome.driver", "C:/PSP/selenium/chromedriver.data");
        WebDriver driver = new ChromeDriver();
        return driver;
    }

    public static WebDriver createFireFoxDriver() {
        System.setProperty("webdriver.firefox.bin", "C:/Program Files (x86)/Mozilla Firefox/firefox.exe");
        WebDriver driver;
        driver = new FirefoxDriver();
        return driver;
    }

jmx

Submitted by Lizhe on Thu, 05/19/2016 - 15:31

JAVA_OPTS="$JAVA_OPTS "-Dcom.sun.management.jmxremote=true" "-Dcom.sun.management.jmxremote.port=7091" "-Dcom.sun.management.jmxremote.authenticate=false" "-Dcom.sun.management.jmxremote.ssl=false" "-Djava.rmi.server.hostname=169.193.148.71

 

-Djava.rmi.server.hostname=10.10.8.57 -Dcom.sun.management.jmxremote  -Dcom.sun.management.jmxremote.port=8011 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false

tomcat config

Submitted by Lizhe on Tue, 03/29/2016 - 23:01

DataPicker/WEB-INF/classes

<Context path="" reloadable="true" docBase="E:\Study\EclipseWorkSpace\DataPicker" workDir="E:\Study\EclipseWorkSpace\DataPicker\work">

</Context>
 

E:\apache-tomcat-7.0.67\conf\Catalina\localhost\ROOT.xml