0%

The following code contains an example, in which a static method is called via a null reference.

1
2
3
4
5
6
7
8
9
public class Test {
public static void main(String... args) {
Test test = null;
test.greeting(); // call with null reference
}
public static void greeting() {
System.out.println("Hello World");
}
}

Because Test::greeting is a static method, the expression test.greeting() is identical to Test.greeting().

For that reason, there is no NullPointerException thrown at runtime.

reference:

线程同步与线程安全

Vector 是线程同步的,而ArrayList不是;

线程同步和线程安全意味着同一时间只允许一个线程访问数据;

Vector 类中的所有方法都是线程同步的,这就解析了为什么创建Vector 对象时就属于线程同步的了。

性能对比

就两者相比较,Vector 属于线程同步的,其性能相对低,而ArrayList 相对较快,因为ArrayList 允许两个或多个线程同时访问数据,而Vector 则限制同一时间只允许一个线程访问数据。

自动增长容量

Vector 默认按当前大小的两倍增长,而ArrayList 是按50%长度增长,当你往Arraylist 中插入元素(当填满元素)

Arraylist 的默认大小为10,Arraylist 会检查是否到了最后一个元素,然后会创建新的数组,复制原数组的数据到新数组,原数组由jvm回收。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//ArrayList源码
/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;


//Vector源码
/**
* Constructs an empty vector so that its internal data array
* has size {@code 10} and its standard capacity increment is
* zero.
*/
public Vector() {
this(10);
}

设定增长大小

ArrayList 不能指定增长长度,而Vector 可以指定增长长度,你可以通过Vector 类的下面方法指定增长长度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public synchronized void setSize(int i) {
//some code
}

//来自源码
/**
* Sets the size of this vector. If the new size is greater than the
* current size, new {@code null} items are added to the end of
* the vector. If the new size is less than the current size, all
* components at index {@code newSize} and greater are discarded.
*
* @param newSize the new size of this vector
* @throws ArrayIndexOutOfBoundsException if the new size is negative
*/
public synchronized void setSize(int newSize) {
modCount++;
if (newSize > elementCount) {
ensureCapacityHelper(newSize);
} else {
for (int i = newSize ; i < elementCount ; i++) {
elementData[i] = null;
}
}
elementCount = newSize;
}

枚举

除了HashTable,Vector 是同时使用了枚举和迭代的唯一一个类,而ArrayList 只能用迭代器遍历一个ArrayList 对象。

官方定义

java.util.Vector自jdk1.0就出现了,java.util.ArrayList在jdk1.2中被作为Java 集合框架介绍过;在jdk1.2版本,Vector 类已经被重构实现List 接口。

reference:

  1. @Inject注解

    @Inject注解可以出现在三种类成员之前:构造器、方法、属性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    //构造器,不含参数的构造器也可以使用@Inject 注解
    @Inject public MurmurMessage(Header header, Content content)
    {
    this.header = header;
    this.content = content;
    }

    //方法
    @Inject public void setContent(Content content)
    {
    this.content = content;
    }

    //属性
    public class MurmurMessenger
    {
    @Inject private MurmurMessage murmurMessage;
    //...
    }
  2. @Qualifier注解

    @Qualifier注解区分同一类型MusicGenre的不用bean

    必须标记为@Qualifier@Retention(RUNTIME),以确保该限定注解运行时一直有效

    通常还会加上@Documented注解,从而该实现就能加API的公共Javadoc中

    可以有属性

    @Target注解可以限定其使用范围

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    @Documented
    @Retention(RUNTIME)
    @Qualifier
    public @interface MusicGenre
    {
    Genre genre() default Genre.TRANCE;
    public enum GENRE { CLASSICAL, METAL, ROCK, TRANCE }
    }

    public class MetalRecordAlbumns
    {
    @Inject @MusicGenre(GENRE.METAL) Genre genre;
    }
  3. @Named注解

    @Named@Inject一起使用,符合指定名称并且类型正确的对象会被注入

    1
    2
    3
    4
    5
    6
    7
    //注入了名称为“murmur”和“broadcast”的两个MurmurMessage对象
    public class MurmurMessenger
    {
    @Inject @Named("murmur") private MurmurMessage murmurMessage;
    @Inject @Named("broadcast") private MurmurMessage broadcastMessage;
    //...
    }
  4. @Singleton注解

    1
    2
    3
    4
    5
    //单例模式
    public MurmurMessage
    {
    @Inject @Singleton MessageHeader defaultHeader;
    }
  5. 接口Provider

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    import com.google.inject.Inject;
    import com.google.inject.Provider;

    class MurmurMessage
    {
    @Inject MurmurMessage (Provider<Message> messageProvider)
    {
    Message msg1 = messageProvider.get();
    if (someGlobalCondition)
    {
    Message copyOfMsg1 = messageProvider.get();
    }
    //...
    }
    }
  6. Google Guice使用入门

  7. Github google/guice wiki

  1. 异步I/O操作

    • 异步I/O-将来式

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      public static void main(String[] args) {
      try {
      Path file = Paths.get("/usr/karianna/foobar.txt");
      //异步打开文件
      AsynchronousFileChannel channel = AsynchronousFileChannel
      .open(file);

      ByteBuffer buffer = ByteBuffer.allocate(100_000);
      Future<Integer> result = channel.read(buffer, 0);
      //判断result是否结束
      while (!result.isDone()) {
      ProfitCalculator.calculateTax();
      }

      Integer bytesRead = result.get();
      System.out.println("Bytes read [" + bytesRead + "]");
      } catch (IOException | ExecutionException | InterruptedException e) {
      System.out.println(e.getMessage());
      }
      }

      private static class ProfitCalculator {

      public ProfitCalculator() {
      }

      public static void calculateTax() {
      }
      }
    • 异步I/O-回调式

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      public static void main(String[] args) {
      try {
      Path file = Paths.get("/usr/karianna/foobar.txt");
      AsynchronousFileChannel channel = AsynchronousFileChannel
      .open(file);

      ByteBuffer buffer = ByteBuffer.allocate(100_000);

      channel.read(buffer, 0, buffer,
      new CompletionHandler<Integer, ByteBuffer>() {

      @Override
      public void completed(Integer result,
      ByteBuffer attachment) {
      System.out.println("Bytes read [" + result + "]");
      }

      @Override
      public void failed(Throwable exception,
      ByteBuffer attachment) {
      System.out.println(exception.getMessage());
      }
      });
      } catch (IOException e) {
      System.out.println(e.getMessage());
      }
      }
  2. NetworkChannel
    获取当前主机networkinterface列表

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    public static void main(String[] args) {
    try {
    Enumeration<NetworkInterface> interfaceList = NetworkInterface
    .getNetworkInterfaces();
    if (null == interfaceList) {
    System.out.println("--No intercaces found--");
    } else {
    while (interfaceList.hasMoreElements()) {
    NetworkInterface iface = interfaceList.nextElement();
    System.out.println("Interface " + iface.getName() + ":");
    Enumeration<InetAddress> addrList = iface
    .getInetAddresses();
    if (!addrList.hasMoreElements()) {
    System.out
    .println("\t(No addresses for this interface)");
    }
    while (addrList.hasMoreElements()) {
    InetAddress address = addrList.nextElement();
    System.out
    .print("\tAddress "
    + ((address instanceof Inet4Address ? "(v4)"
    : (address instanceof Inet6Address ? "(v6)"
    : "(?)"))));
    System.out.println(": " + address.getHostAddress());
    }
    }
    }
    } catch (SocketException se) {
    System.out.println("Error getting network interfaces:"
    + se.getMessage());
    }
    }

  1. 二进制文本
    让 int x 用位模式表示十进制值102

    1
    2
    3
    4
    //Java 7 之前的写法:
    int x = Integer.parseInt("1100110",2);
    //Java 7 的写法:
    int x = 0b1100110;
  2. 数字中的下划线

    1
    long tmp=1_000_000;
  3. final重抛

    1
    2
    3
    4
    5
    6
    7
    try {
    doSomethingWhichMightThrowIOException();
    doSomethingElseWhichMightThrowSQLException();
    } catch (final Exception e) {
    ...
    throw e;
    }
  4. Try-with-resources (TWR)

    1
    2
    3
    4
    5
    6
    7
    8
    try (OutputStream out = new FileOutputStream(file);
    InputStream is = url.openStream() ) {
    byte[] buf = new byte[4096];
    int len;
    while ((len = is.read(buf)) > 0) {
    out.write(buf, 0, len);
    }
    }
  5. Java 7钻石语法

    1
    2
    3
    4
    //不用钻石语法
    Map<Integer, Map<String, String>> usersLists =new HashMap<Integer, Map<String, String>>();
    //使用钻石语法,上面语句少了j近一半字符
    Map<Integer, Map<String, String>> usersLists = new HashMap<>();
  6. Java 7处理符号链接

    1
    2
    3
    4
    java.nio.file.Path path = java.nio.file.Paths.get("/ftp/upload/1.jpg");
    java.nio.file.Path path2 = java.nio.file.Paths.get("/ftp/upload/2.jpg").toRealPath();
    System.out.println(path.toRealPath());
    System.out.println(path2.toString());

    其中:

    1
    2
    -rwxrwxrwx 1 lau  lau  191221  816  2014 1.jpg*
    lrwxrwxrwx 1 root root 17 811 12:23 2.jpg -> /ftp/upload/1.jpg*

    输出:

    1
    2
    /ftp/upload/1.jpg
    /ftp/upload/1.jpg
  7. Java 7在目录中查找文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // Java 7在目录中查找文件
    java.nio.file.Path path = java.nio.file.Paths
    .get("F:\\Pictures\\WeixinPictures");
    try (java.nio.file.DirectoryStream<java.nio.file.Path> stream =
    java.nio.file.Files.newDirectoryStream(path, "*jpg")) {
    for (java.nio.file.Path path2 : stream) {
    System.out.println(path2.getFileName());

    }
    } catch (Exception e) {
    System.out.println(e.getMessage());
    }
  8. Java 7遍历目录树

    1
    2
    3
    4
    5
    6
    7
    8
    // Java 7遍历目录树
    java.nio.file.Path startingDir = java.nio.file.Paths.get("F:\\Pictures");

    try {
    java.nio.file.Files.walkFileTree(startingDir, new FindJPGVisitor());
    } catch (IOException e) {
    System.out.println(e.getMessage());
    }
  9. NIO.2的文件系统I/O

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    //创建文件
    Path target = Paths.get("D:\\Backup\\MyStuff.txt");
    Path file = Files.createFile(target);

    //创建文件,带权限
    Path target = Paths.get("D:\\Backup\\MyStuff.txt");
    Set<PosixFilePermission> perms =
    PosixFilePermissions.fromString("rw-rw-rw-");
    FileAttribute<Set<PosixFilePermission>> attr =
    PosixFilePermissions.asFileAttribute(perms);
    Files.createFile(target, attr);

    //复制文件
    Path source = Paths.get("C:\\My Documents\\Stuff.txt");
    Path target = Paths.get("D:\\Backup\\MyStuff.txt");
    Files.copy(source, target);

    //删除文件
    Path target = Paths.get("D:\\Backup\\MyStuff.txt");
    Files.delete(target);

    //符号链接
    Path file = Paths.get("/ftp/upload/2.jpg");
    try{
    if(Files.isSymbolicLink(file)){
    file = Files.readSymbolicLink(file);
    }
    Files.readAttributes(file, BasicFileAttributes.class);
    }
    catch (IOException e){
    System.out.println(e.getMessage());
    }

    //打开文件,注意编码
    Path logFile = Paths.get("/tmp/app.log");
    try (BufferedReader reader =
    Files.newBufferedReader(logFile, StandardCharsets.UTF_8)) {
    String line;
    while ((line = reader.readLine()) != null) {
    //...
    }
    }

    //写入文件
    Path logFile = Paths.get("/tmp/app.log");
    try (BufferedWriter writer =
    Files.newBufferedWrite(logFile, StandardCharsets.UTF_8,
    StandardOpenOption.WRITE)) {
    writer.write("Hello World!");
    //...
    }

    //简化读取和写入,没必要再用while循环把数据从字节数组读到缓冲区里
    Path logFile = Paths.get("/tmp/app.log");
    List<String> lines = Files.readAllLines(logFile, StandardCharsets.UTF_8);
    byte[] bytes = Files.readAllBytes(logFile);

MarkdownEditing

Markdown plugin for Sublime Text.

Provides a decent Markdown color scheme (light and dark) with more robust syntax highlighting and useful Markdown editing features for Sublime Text.

3 flavors are supported: Standard Markdown, GitHub flavored Markdown, MultiMarkdown.

MarkdownEditing

Markdown Preview

Preview and build your markdown files quickly in your web browser from sublime text 2/3.

You can use builtin [python-markdown][10] parser or use the [github markdown API][5] for the conversion.

NOTE: If you choose the GitHub API for conversion (set parser: github in your settings), your code will be sent through https to github for live conversion. You’ll have [Github flavored markdown][6], syntax highlighting and EMOJI support for free :heart: :octocat: :gift:. If you make more than 60 calls a day, be sure to set your GitHub API key in the settings :). You can also get most of this in the default Markdown parser with by enabling certain extensions; see “Parsing Github Flavored Markdown“” below for more information.

LINUX users: If you want to use GitHub API for conversion, you’ll need to have a custom Python install that includes python-ssl as its not built in the Sublime Text 2 Linux package. see [@dusteye comment][8]. If you use a custom window manager, also be sure to set a BROWSER environment variable. see [@PPvG comments][9]

sublimetext-markdown-preview

在线播放

歌曲鉴赏(来自 百度百科

这首歌曲淡淡地给我们讲述了一对恋人的爱情故事。

他们双方本没有料到上天会将他们安排在一起。

只是当爱不知不觉地到来时,他们才意识到。

爱的到来打乱了男女那平静的心房,他们都不知道该如何对待这一份爱情。

他们快乐地依偎在一起,正如歌曲中的“我飘呀飘,你摇啊摇”。路边的野草是他们爱情的见证。

但是,这美好的一切似乎是一场梦,当他们回到现实中来时,却发现爱情有时也会使人烦恼、哀愁,想爱又怕受伤;不爱呢,那颗心又不能平静。

爱情就这样让人摸不到头脑。

这对恋人面对爱情的考验时,他们选择了让爱情一次性地痛快燃烧。

要爱就要爱得快乐,爱得纯真,爱得潇洒,也就是爱要爱得“飘摇”。

歌词

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
風停了雲知道
愛走了心自然明了
他來時躲不掉
他走得靜悄悄
你不在我預料
擾亂我平靜的步調
怕愛了找苦惱
怕不愛睡不著
我飄啊飄 你搖啊搖
無根的野草
當夢醒了 天晴了
如何再飄搖
啊 愛多一秒 恨不會少
承諾是煎熬
若不計較 就一次 痛快燃燒
往往愛上一個人就只要在一剎那
就這樣 我深深的
被你的眼神打動
但 我又該如何呢
就讓一切隨緣吧 也但願
你也一樣會珍惜那一剎那
所帶來的一切
你不在我預料
擾亂我平靜的步調
怕愛了找苦惱
怕不愛睡不著
我飄啊飄 你搖啊搖
無根的野草
當夢醒了 天晴了 如何再飄搖
啊 愛多一秒 恨不會少
承諾是煎熬
若不計較 就一次 痛快燃燒
我飄啊飄 你搖啊搖
無根的野草
當夢醒了 天晴了
如何再飄搖
愛多一秒 恨不會少
承諾是煎熬
若不計較 就一次痛快燃燒
若不計較 就一次 痛快燃燒

Remark: Finished read 1-7, 2015-07-23 15:40:57

Multithreading in Java is a very important topic. I have written a lot about Threads in Java. Java Thread is a lightweight process that executes some task. Java provides multithreading support with the Thread class and an application can create multiple threads executing concurrently.

multithreading-in-java.jpg

There are two types of threads in an application – user thread and daemon thread. When we start an application, main is the first user thread created and we can create multiple user threads as well as daemon threads. When all the user threads are executed, JVM terminates the program.

We can set different priorities to different Threads but it doesn’t guarantee that higher priority thread will execute first than lower priority thread. Thread scheduler is the part of Operating System implementation and when a Thread is started, it’s execution is controlled by Thread Scheduler and JVM doesn’t have any control on it’s execution.

We can create Threads by either implementing Runnable interface or by extending Thread Class.

1
2
3
4
5
Thread t = new Thread(new Runnable(){
@Override
public void run() {
}
});

Above is a one liner statement to create new Thread, Here we are creating Runnable as Anonymous Class, read this post to learn about inner class, nested class and anonymous inner class.

In last few weeks, I have posted some useful articles on multithreading in java, you can follow them in order to learn about Threads in Java.

Threads in Java

java-thread.png

With Java 8 lambda expressions, we can create Thread in java like below too because Runnable is a functional interface.

  1. Java Thread Example

    This is the first post in the multithreading in java tutorial series. Read this to learn about Process and Thread. What is the difference between Thread and Process. Benefits of using Threads and how we can create Threads using Runnable interface and Thread class. This post also compares Runnable interface with Thread class.

  2. Java Thread Sleep

    Java Thread sleep is used to pause the execution of current thread. We will use Thread sleep extensively in future posts, so it’s good to know how it works and is it accurate or not?

  3. Java Thread Join

    Sometimes we need to wait for other threads to finish it’s execution before we can proceed. We can achieve this using Thread join, learn how it works and when we should use it.

  4. Java Thread States

    Understanding different states of thread is important. Learn how thread changes it’s state and how thread scheduler changes thread state.

  5. Java Thread wait, notify and notifyAll

    Java Object class contains three methods using which threads can communicate about the lock status of a resource. Learn with example usage of these Object class methods in a simple Wait-Notify implementation.

  6. Java Thread Safety and Java Synchronization

    We know that Threads share Object resources, it can lead to data corruption because these operations are not atomic. Learn how we can achieve thread safety in java using different methods. Read this post to learn about the correct usage of synchronization, synchronized methods and synchronized blocks.
    There are various examples of synchronized usage and the post explains what are the issues with them.

  7. Java Exception in thread main

    JVM creates first thread using main method. This post explains about some common exceptions we see in daily life and what is the root cause of them and how to fix them.

  8. Thread Safety in Singleton Class

    In this article, you will learn basic concepts of creating Singleton class. What are thread safety issues with different implementation. How we can achieve thread safety in Singleton class.

  9. Daemon Thread in Java

    A simple article explaining about daemon threads and how we can create daemon threads in java.

  10. Java Thread Local

    We know that threads share Object’s variables but what if we want to have thread-local variables created at class level. Java provides ThreadLocal utility class to create thread-local variables. Read more to learn about how we can create ThreadLocal variables in java program.

  11. Java Thread Dump

    Java Thread dump provides the current threads information for the program. Java Thread dump provides useful information to analyze performance issues with the application. You can use thread dump to find and fix deadlock situations. This post explains different methods that can be used to generate thread dump in java.

  12. How to Analyze Deadlock and avoid it in Java

    Deadlock is a situation where multiple threads are waiting for each other to release resources causing cyclic dependency. This article discusses about the situation in which we can get deadlock in a java program. How we can use Thread dump to find the deadlock and best practices to avoid deadlock in java program.

  13. Java Timer Thread

    This post explains how we can use Java Timer and TimerTask classes to create jobs to run at scheduled interval, an example program showing it’s usage and how we can cancel the timer.

  14. Java Producer Consumer Problem

    Before Java 5, producer-consumer problem can be solved using wait() and notify() methods but introduction of BlockingQueue has made it very easy. Learn how we can use BlockingQueue to solve producer consumer problem in java.

  15. Java Thread Pool

    Java Thread Pool is a collection of worker threads waiting to process jobs. Java 5 introduction of Executor framework has made it very easy to create thread pool in java using Executors and ThreadPoolExecutor classes. Learn how to use them to create thread pool in java.

  16. Java Callable Future

    Sometimes we wish Thread could return values that we can use. Java 5 Callable can be used in that case that is similar as Runnable interface. We can use Executor framework to execute Callable tasks.

  17. Java FutureTask Example

    FutureTask class is the base concrete class that implements Future interface. We use it with Callable implementation and Executors for asynchronous processing. FutureTask provide implementation methods to check the state of the task and return the value to the calling program once it’s processing is finished. It comes handy when you want to override some of the implementation methods of the Future interface.