();
+ list.add("s2");
+ list.add("s4");
+ list.add("s1");
+ list.add("s3");
+ System.out.println(list);
+ Collections.addAll(list, "s5","s7",null,"s9");
+ System.out.println(list);
+}
}
diff --git a/src/org/javacore/collection/util/IterAndListIterT.java b/src/main/java/org/javacore/collection/util/IterAndListIterT.java
similarity index 100%
rename from src/org/javacore/collection/util/IterAndListIterT.java
rename to src/main/java/org/javacore/collection/util/IterAndListIterT.java
diff --git a/src/org/javacore/collection/util/PerBtwnEmptyMapAndHashMapT.java b/src/main/java/org/javacore/collection/util/PerBtwnEmptyMapAndHashMapT.java
similarity index 100%
rename from src/org/javacore/collection/util/PerBtwnEmptyMapAndHashMapT.java
rename to src/main/java/org/javacore/collection/util/PerBtwnEmptyMapAndHashMapT.java
diff --git a/src/main/java/org/javacore/concurrent/CountDownLatchT.java b/src/main/java/org/javacore/concurrent/CountDownLatchT.java
new file mode 100644
index 0000000..34e6677
--- /dev/null
+++ b/src/main/java/org/javacore/concurrent/CountDownLatchT.java
@@ -0,0 +1,48 @@
+package org.javacore.concurrent;
+
+import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 同步辅助类:完成一组线程执行前,使得一个或多个线程一直等待
+ *
+ * Created by bysocket on 16/4/26.
+ */
+public class CountDownLatchT {
+
+ // 线程中止的计数器
+ private final static int COUNT = 10;
+ private final static CountDownLatch count = new CountDownLatch(COUNT);
+
+ // 线程池
+ private final static ExecutorService service = Executors.newFixedThreadPool(5);
+
+ public static void main(String[] args) throws InterruptedException {
+ for (int i = 0; i < COUNT; i++) { + service.execute(() -> {
+ try {
+ int time = new Random().nextInt(5);
+ TimeUnit.SECONDS.sleep(time);
+ System.out.printf("Thread %s ## 耗时:%d\n", Thread.currentThread().getId(), time);
+ // 线程结束后,计数器减一
+ count.countDown();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ });
+ }
+
+ // 主线程一直被阻塞,直到count为0,实现线程同步
+ count.await();
+ service.shutdown();
+
+ System.out.println("同步线程执行组结束!");
+
+ }
+}
+
+
diff --git a/src/main/java/org/javacore/img/ImgCircleCut.java b/src/main/java/org/javacore/img/ImgCircleCut.java
new file mode 100644
index 0000000..ecb5bf9
--- /dev/null
+++ b/src/main/java/org/javacore/img/ImgCircleCut.java
@@ -0,0 +1,60 @@
+package org.javacore.img;
+
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.geom.Ellipse2D;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2016年06月28日 14:05:26
+ * 图片裁成椭圆
+ */
+public class ImgCircleCut {
+
+ public static boolean ImgCircleCut(String srcFile, String targetFile) {
+ try {
+ // 获取img的BufferedImage对象,可以考虑创建不带透明色的BufferedImage对象:BufferedImage.TYPE_INT_ARGB
+ BufferedImage srcBi = ImageIO.read(new File(srcFile));
+ // 创建一个带透明色的BufferedImage对象
+ BufferedImage targetBi = new BufferedImage(srcBi.getWidth(), srcBi.getHeight(),
+ BufferedImage.TYPE_INT_ARGB);
+ // 获取img窗体矩形定义的椭圆
+ Ellipse2D.Double shape = new Ellipse2D.Double(0, 0,
+ srcBi.getWidth(), srcBi.getHeight());
+ // 创建目标图的Graphics2D对象
+ Graphics2D g2 = targetBi.createGraphics();
+ // 创建不透明 SRC_OVER 规则的 AlphaComposite 对象
+ AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.9f);
+ g2.setComposite(ac);
+ g2.setBackground(new Color(22, 2, 2, 0));
+ // 是圆形 还是 椭圆 自定义参数
+ g2.fill3DRect(200, 200, 180, 80, false);
+ g2.setClip(shape);
+ g2.drawImage(srcBi, 0, 0, null);
+ g2.dispose();
+ ImageIO.write(targetBi, "png", new File(targetFile));
+ } catch (IOException e) {
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/src/org/javacore/initAndCleanup/SimpleConstructor.java b/src/main/java/org/javacore/initAndCleanup/SimpleConstructor.java
similarity index 100%
rename from src/org/javacore/initAndCleanup/SimpleConstructor.java
rename to src/main/java/org/javacore/initAndCleanup/SimpleConstructor.java
diff --git a/src/org/javacore/initAndCleanup/SimpleConstructor2.java b/src/main/java/org/javacore/initAndCleanup/SimpleConstructor2.java
similarity index 100%
rename from src/org/javacore/initAndCleanup/SimpleConstructor2.java
rename to src/main/java/org/javacore/initAndCleanup/SimpleConstructor2.java
diff --git a/src/org/javacore/initAndCleanup/VoidConstructor.java b/src/main/java/org/javacore/initAndCleanup/VoidConstructor.java
similarity index 100%
rename from src/org/javacore/initAndCleanup/VoidConstructor.java
rename to src/main/java/org/javacore/initAndCleanup/VoidConstructor.java
diff --git a/src/org/javacore/io/BufferedInputFileT.java b/src/main/java/org/javacore/io/BufferedInputFileT.java
similarity index 100%
rename from src/org/javacore/io/BufferedInputFileT.java
rename to src/main/java/org/javacore/io/BufferedInputFileT.java
diff --git a/src/main/java/org/javacore/io/ChangeSystemOut.java b/src/main/java/org/javacore/io/ChangeSystemOut.java
new file mode 100644
index 0000000..36ac78a
--- /dev/null
+++ b/src/main/java/org/javacore/io/ChangeSystemOut.java
@@ -0,0 +1,31 @@
+package org.javacore.io;
+
+import java.io.PrintWriter;
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年10月6日 18:38:15
+ * 改变System.out输出案例
+ */
+public class ChangeSystemOut {
+ public static void main(String[] args) {
+ PrintWriter out = new PrintWriter(System.out,true);
+ out.println("Hello PrintWriter");
+ out.close();
+ }
+}
diff --git a/src/org/javacore/io/CopyFileT.java b/src/main/java/org/javacore/io/CopyFileT.java
similarity index 100%
rename from src/org/javacore/io/CopyFileT.java
rename to src/main/java/org/javacore/io/CopyFileT.java
diff --git a/src/org/javacore/io/DirListT.java b/src/main/java/org/javacore/io/DirListT.java
similarity index 100%
rename from src/org/javacore/io/DirListT.java
rename to src/main/java/org/javacore/io/DirListT.java
diff --git a/src/org/javacore/io/Directory.java b/src/main/java/org/javacore/io/Directory.java
similarity index 100%
rename from src/org/javacore/io/Directory.java
rename to src/main/java/org/javacore/io/Directory.java
diff --git a/src/main/java/org/javacore/io/FileIOStreamT.java b/src/main/java/org/javacore/io/FileIOStreamT.java
new file mode 100644
index 0000000..4f67287
--- /dev/null
+++ b/src/main/java/org/javacore/io/FileIOStreamT.java
@@ -0,0 +1,52 @@
+package org.javacore.io;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年10月8日 20:06:03
+ * FileInputStream&FileOutputStream使用案例
+ */
+public class FileIOStreamT {
+ private static final String thisFilePath =
+ "src" + File.separator +
+ "org" + File.separator +
+ "javacore" + File.separator +
+ "io" + File.separator +
+ "FileIOStreamT.java";
+ public static void main(String[] args) throws IOException {
+ // 创建文件输入流
+ FileInputStream fileInputStream = new FileInputStream(thisFilePath);
+ // 创建文件输出流
+ FileOutputStream fileOutputStream = new FileOutputStream("data.txt");
+
+ // 创建流的最大字节数组
+ byte[] inOutBytes = new byte[fileInputStream.available()];
+ // 将文件输入流读取,保存至inOutBytes数组
+ fileInputStream.read(inOutBytes);
+ // 将inOutBytes数组,写出到data.txt文件中
+ fileOutputStream.write(inOutBytes);
+
+ fileOutputStream.close();
+ fileInputStream.close();
+ }
+}
diff --git a/src/org/javacore/io/FileMethodsT.java b/src/main/java/org/javacore/io/FileMethodsT.java
similarity index 100%
rename from src/org/javacore/io/FileMethodsT.java
rename to src/main/java/org/javacore/io/FileMethodsT.java
diff --git a/src/org/javacore/io/FileT.java b/src/main/java/org/javacore/io/FileT.java
similarity index 100%
rename from src/org/javacore/io/FileT.java
rename to src/main/java/org/javacore/io/FileT.java
diff --git a/src/org/javacore/io/FilenameFilterT.java b/src/main/java/org/javacore/io/FilenameFilterT.java
similarity index 100%
rename from src/org/javacore/io/FilenameFilterT.java
rename to src/main/java/org/javacore/io/FilenameFilterT.java
diff --git a/src/org/javacore/io/FormatteMemoryInput.java b/src/main/java/org/javacore/io/FormatteMemoryInput.java
similarity index 100%
rename from src/org/javacore/io/FormatteMemoryInput.java
rename to src/main/java/org/javacore/io/FormatteMemoryInput.java
diff --git a/src/org/javacore/io/JavaFileListT.java b/src/main/java/org/javacore/io/JavaFileListT.java
similarity index 100%
rename from src/org/javacore/io/JavaFileListT.java
rename to src/main/java/org/javacore/io/JavaFileListT.java
diff --git a/src/org/javacore/io/MemoryInputT.java b/src/main/java/org/javacore/io/MemoryInputT.java
similarity index 100%
rename from src/org/javacore/io/MemoryInputT.java
rename to src/main/java/org/javacore/io/MemoryInputT.java
diff --git a/src/main/java/org/javacore/io/OSExecuteT.java b/src/main/java/org/javacore/io/OSExecuteT.java
new file mode 100644
index 0000000..ecda29d
--- /dev/null
+++ b/src/main/java/org/javacore/io/OSExecuteT.java
@@ -0,0 +1,72 @@
+package org.javacore.io;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年10月6日 18:40:24
+ * 操作系统进程流的案例
+ */
+public class OSExecuteT {
+ public static void commond(String command) {
+ boolean err = false;
+
+ try {
+ // 创建操作系统进程
+ Process process =
+ new ProcessBuilder(command.split(" ")).start();
+
+ // 读取进程的输入流
+ BufferedReader results = new BufferedReader(
+ new InputStreamReader(process.getInputStream()));
+ String s;
+ while ((s = results.readLine()) != null)
+ System.out.println(s);
+
+ // 读取进程的错误流
+ BufferedReader errors = new BufferedReader(
+ new InputStreamReader(process.getErrorStream()));
+ while ((s = errors.readLine()) != null) {
+ System.err.println(s);
+ if (!err)
+ err = true;
+ }
+
+ } catch (Exception e) {
+ if (!command.startsWith("CMD /C"))
+ commond("CMD /C " + command);
+ else
+ throw new RuntimeException(e);
+ }
+
+ if (err)
+ throw new OSExecuteException("Errors Executing " + command);
+ }
+
+ public static void main(String[] args) {
+ commond("java -version");
+ }
+}
+class OSExecuteException extends RuntimeException {
+ private static final long serialVersionUID = -3254218368058055219L;
+
+ public OSExecuteException(String msg) {
+ super(msg);
+ }
+}
diff --git a/src/org/javacore/io/PipeStreamT.java b/src/main/java/org/javacore/io/PipeStreamT.java
similarity index 100%
rename from src/org/javacore/io/PipeStreamT.java
rename to src/main/java/org/javacore/io/PipeStreamT.java
diff --git a/src/org/javacore/io/RandomAccessFileT.java b/src/main/java/org/javacore/io/RandomAccessFileT.java
similarity index 100%
rename from src/org/javacore/io/RandomAccessFileT.java
rename to src/main/java/org/javacore/io/RandomAccessFileT.java
diff --git a/src/main/java/org/javacore/io/SByteArrayInputStream.java b/src/main/java/org/javacore/io/SByteArrayInputStream.java
new file mode 100644
index 0000000..f0bd662
--- /dev/null
+++ b/src/main/java/org/javacore/io/SByteArrayInputStream.java
@@ -0,0 +1,258 @@
+//package org.javacore.io;
+//
+//import java.io.IOException;
+//import java.io.InputStream;
+//
+///**
+// * A ByteArrayInputStream contains
+// * an internal buffer that contains bytes that
+// * may be read from the stream. An internal
+// * counter keeps track of the next byte to
+// * be supplied by the read method.
+// *
+// * Closing a ByteArrayInputStream has no effect. The methods in
+// * this class can be called after the stream has been closed without
+// * generating an IOException.
+// */
+//public
+//class SByteArrayInputStream extends InputStream {
+//
+// /**
+// * An array of bytes that was provided
+// * by the creator of the stream. Elements buf[0]
+// * through buf[count-1] are the
+// * only bytes that can ever be read from the
+// * stream; element buf[pos] is
+// * the next byte to be read.
+// */
+// protected byte buf[];
+//
+// /**
+// * The index of the next character to read from the input stream buffer.
+// * This value should always be nonnegative
+// * and not larger than the value of count.
+// * The next byte to be read from the input stream buffer
+// * will be buf[pos].
+// */
+// protected int pos;
+//
+// /**
+// * The currently marked position in the stream.
+// * ByteArrayInputStream objects are marked at position zero by
+// * default when constructed. They may be marked at another
+// * position within the buffer by the mark() method.
+// * The current buffer position is set to this point by the
+// * reset() method.
+// *
+// * If no mark has been set, then the value of mark is the offset
+// * passed to the constructor (or 0 if the offset was not supplied).
+// *
+// * @since JDK1.1
+// */
+// protected int mark = 0;
+//
+// /**
+// * The index one greater than the last valid character in the input
+// * stream buffer.
+// * This value should always be nonnegative
+// * and not larger than the length of buf.
+// * It is one greater than the position of
+// * the last byte within buf that
+// * can ever be read from the input stream buffer.
+// */
+// protected int count;
+//
+// /**
+// * Creates a ByteArrayInputStream
+// * so that it uses buf as its
+// * buffer array.
+// * The buffer array is not copied.
+// * The initial value of pos
+// * is 0 and the initial value
+// * of count is the length of
+// * buf.
+// *
+// * @param buf the input buffer.
+// */
+// public ByteArrayInputStream(byte buf[]) {
+// this.buf = buf;
+// this.pos = 0;
+// this.count = buf.length;
+// }
+//
+// /**
+// * Creates ByteArrayInputStream
+// * that uses buf as its
+// * buffer array. The initial value of pos
+// * is offset and the initial value
+// * of count is the minimum of offset+length
+// * and buf.length.
+// * The buffer array is not copied. The buffer's mark is
+// * set to the specified offset.
+// *
+// * @param buf the input buffer.
+// * @param offset the offset in the buffer of the first byte to read.
+// * @param length the maximum number of bytes to read from the buffer.
+// */
+// public ByteArrayInputStream(byte buf[], int offset, int length) {
+// this.buf = buf;
+// this.pos = offset;
+// this.count = Math.min(offset + length, buf.length);
+// this.mark = offset;
+// }
+//
+// /**
+// * Reads the next byte of data from this input stream. The value
+// * byte is returned as an int in the range
+// * 0 to 255. If no byte is available
+// * because the end of the stream has been reached, the value
+// * -1 is returned.
+// *
+// * This read method
+// * cannot block.
+// *
+// * @return the next byte of data, or -1 if the end of the
+// * stream has been reached.
+// */
+// public synchronized int read() {
+// return (pos < count) ? (buf[pos++] & 0xff) : -1; +// } +// +// /** +// * Reads up to len bytes of data into an array of bytes
+// * from this input stream.
+// * If pos equals count,
+// * then -1 is returned to indicate
+// * end of file. Otherwise, the number k
+// * of bytes read is equal to the smaller of
+// * len and count-pos.
+// * If k is positive, then bytes
+// * buf[pos] through buf[pos+k-1]
+// * are copied into b[off] through
+// * b[off+k-1] in the manner performed
+// * by System.arraycopy. The
+// * value k is added into pos
+// * and k is returned.
+// *
+// * This read method cannot block.
+// *
+// * @param b the buffer into which the data is read.
+// * @param off the start offset in the destination array b
+// * @param len the maximum number of bytes read.
+// * @return the total number of bytes read into the buffer, or
+// * -1 if there is no more data because the end of
+// * the stream has been reached.
+// * @exception NullPointerException If b is null.
+// * @exception IndexOutOfBoundsException If off is negative,
+// * len is negative, or len is greater than
+// * b.length - off
+// */
+// public synchronized int read(byte b[], int off, int len) {
+// if (b == null) {
+// throw new NullPointerException();
+// } else if (off < 0 || len < 0 || len> b.length - off) {
+// throw new IndexOutOfBoundsException();
+// }
+//
+// if (pos>= count) {
+// return -1;
+// }
+//
+// int avail = count - pos;
+// if (len> avail) {
+// len = avail;
+// }
+// if (len <= 0) { +// return 0; +// } +// System.arraycopy(buf, pos, b, off, len); +// pos += len; +// return len; +// } +// +// /** +// * Skips n bytes of input from this input stream. Fewer
+// * bytes might be skipped if the end of the input stream is reached.
+// * The actual number k
+// * of bytes to be skipped is equal to the smaller
+// * of n and count-pos.
+// * The value k is added into pos
+// * and k is returned.
+// *
+// * @param n the number of bytes to be skipped.
+// * @return the actual number of bytes skipped.
+// */
+// public synchronized long skip(long n) {
+// long k = count - pos;
+// if (n < k) { +// k = n < 0 ? 0 : n; +// } +// +// pos += k; +// return k; +// } +// +// /** +// * Returns the number of remaining bytes that can be read (or skipped over) +// * from this input stream. +// *
+// * The value returned is count - pos,
+// * which is the number of bytes remaining to be read from the input buffer.
+// *
+// * @return the number of remaining bytes that can be read (or skipped
+// * over) from this input stream without blocking.
+// */
+// public synchronized int available() {
+// return count - pos;
+// }
+//
+// /**
+// * Tests if this InputStream supports mark/reset. The
+// * markSupported method of ByteArrayInputStream
+// * always returns true.
+// *
+// * @since JDK1.1
+// */
+// public boolean markSupported() {
+// return true;
+// }
+//
+// /**
+// * Set the current marked position in the stream.
+// * ByteArrayInputStream objects are marked at position zero by
+// * default when constructed. They may be marked at another
+// * position within the buffer by this method.
+// *
+// * If no mark has been set, then the value of the mark is the
+// * offset passed to the constructor (or 0 if the offset was not
+// * supplied).
+// *
+// *
Note: The readAheadLimit for this class
+// * has no meaning.
+// *
+// * @since JDK1.1
+// */
+// public void mark(int readAheadLimit) {
+// mark = pos;
+// }
+//
+// /**
+// * Resets the buffer to the marked position. The marked position
+// * is 0 unless another position was marked or an offset was specified
+// * in the constructor.
+// */
+// public synchronized void reset() {
+// pos = mark;
+// }
+//
+// /**
+// * Closing a ByteArrayInputStream has no effect. The methods in
+// * this class can be called after the stream has been closed without
+// * generating an IOException.
+// *
+// */
+// public void close() throws IOException {
+// }
+//
+//}
+//
diff --git a/src/main/java/org/javacore/io/SFileInputStream.java b/src/main/java/org/javacore/io/SFileInputStream.java
new file mode 100644
index 0000000..2a898e8
--- /dev/null
+++ b/src/main/java/org/javacore/io/SFileInputStream.java
@@ -0,0 +1,184 @@
+//package org.javacore.io;
+//
+//import java.io.File;
+//import java.io.FileDescriptor;
+//import java.io.FileNotFoundException;
+//import java.io.IOException;
+//import java.io.InputStream;
+//import java.nio.channels.FileChannel;
+//
+//import sun.misc.IoTrace;
+//import sun.nio.ch.FileChannelImpl;
+//
+///**
+// * FileInputStream 从文件系统的文件中获取输入字节流。文件取决于主机系统。
+// * 比如读取图片等的原始字节流。如果读取字符流,考虑使用 FiLeReader。
+// */
+//public class SFileInputStream extends InputStream
+//{
+// /* 文件描述符类---此处用于打开文件的句柄 */
+// private final FileDescriptor fd;
+//
+// /* 引用文件的路径 */
+// private final String path;
+//
+// /* 文件通道,NIO部分 */
+// private FileChannel channel = null;
+//
+// private final Object closeLock = new Object();
+// private volatile boolean closed = false;
+//
+// private static final ThreadLocal runningFinalize =
+// new ThreadLocal();
+//
+// private static boolean isRunningFinalize() {
+// Boolean val;
+// if ((val = runningFinalize.get()) != null)
+// return val.booleanValue();
+// return false;
+// }
+//
+// /* 通过文件路径名来创建FileInputStream */
+// public FileInputStream(String name) throws FileNotFoundException {
+// this(name != null ? new File(name) : null);
+// }
+//
+// /* 通过文件来创建FileInputStream */
+// public FileInputStream(File file) throws FileNotFoundException {
+// String name = (file != null ? file.getPath() : null);
+// SecurityManager security = System.getSecurityManager();
+// if (security != null) {
+// security.checkRead(name);
+// }
+// if (name == null) {
+// throw new NullPointerException();
+// }
+// if (file.isInvalid()) {
+// throw new FileNotFoundException("Invalid file path");
+// }
+// fd = new FileDescriptor();
+// fd.incrementAndGetUseCount();
+// this.path = name;
+// open(name);
+// }
+//
+// /* 通过文件描述符类来创建FileInputStream */
+// public FileInputStream(FileDescriptor fdObj) {
+// SecurityManager security = System.getSecurityManager();
+// if (fdObj == null) {
+// throw new NullPointerException();
+// }
+// if (security != null) {
+// security.checkRead(fdObj);
+// }
+// fd = fdObj;
+// path = null;
+// fd.incrementAndGetUseCount();
+// }
+//
+// /* 打开文件,为了下一步读取文件内容。native方法 */
+// private native void open(String name) throws FileNotFoundException;
+//
+// /* 从此输入流中读取一个数据字节 */
+// public int read() throws IOException {
+// Object traceContext = IoTrace.fileReadBegin(path);
+// int b = 0;
+// try {
+// b = read0();
+// } finally {
+// IoTrace.fileReadEnd(traceContext, b == -1 ? 0 : 1);
+// }
+// return b;
+// }
+//
+// /* 从此输入流中读取一个数据字节。native方法 */
+// private native int read0() throws IOException;
+//
+// /* 从此输入流中读取多个字节到byte数组中。native方法 */
+// private native int readBytes(byte b[], int off, int len) throws IOException;
+//
+// /* 从此输入流中读取多个字节到byte数组中。 */
+// public int read(byte b[]) throws IOException {
+// Object traceContext = IoTrace.fileReadBegin(path);
+// int bytesRead = 0;
+// try {
+// bytesRead = readBytes(b, 0, b.length);
+// } finally {
+// IoTrace.fileReadEnd(traceContext, bytesRead == -1 ? 0 : bytesRead);
+// }
+// return bytesRead;
+// }
+//
+// /* 从此输入流中读取最多len个字节到byte数组中。 */
+// public int read(byte b[], int off, int len) throws IOException {
+// Object traceContext = IoTrace.fileReadBegin(path);
+// int bytesRead = 0;
+// try {
+// bytesRead = readBytes(b, off, len);
+// } finally {
+// IoTrace.fileReadEnd(traceContext, bytesRead == -1 ? 0 : bytesRead);
+// }
+// return bytesRead;
+// }
+//
+//
+// public native long skip(long n) throws IOException;
+//
+// /* 返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取(或跳过)的估计剩余字节数。 */
+// public native int available() throws IOException;
+//
+// /* 关闭此文件输入流并释放与此流有关的所有系统资源。 */
+// public void close() throws IOException {
+// synchronized (closeLock) {
+// if (closed) {
+// return;
+// }
+// closed = true;
+// }
+// if (channel != null) {
+// fd.decrementAndGetUseCount();
+// channel.close();
+// }
+//
+// int useCount = fd.decrementAndGetUseCount();
+//
+// if ((useCount <= 0) || !isRunningFinalize()) { +// close0(); +// } +// } +// +// public final FileDescriptor getFD() throws IOException { +// if (fd != null) return fd; +// throw new IOException(); +// } +// +// /* 获取此文件输入流的唯一FileChannel对象 */ +// public FileChannel getChannel() { +// synchronized (this) { +// if (channel == null) { +// channel = FileChannelImpl.open(fd, path, true, false, this); +// fd.incrementAndGetUseCount(); +// } +// return channel; +// } +// } +// +// private static native void initIDs(); +// +// private native void close0() throws IOException; +// +// static { +// initIDs(); +// } +// +// protected void finalize() throws IOException { +// if ((fd != null) && (fd != FileDescriptor.in)) { +// runningFinalize.set(Boolean.TRUE); +// try { +// close(); +// } finally { +// runningFinalize.set(Boolean.FALSE); +// } +// } +// } +//} \ No newline at end of file diff --git a/src/main/java/org/javacore/io/SFileOutputStream.java b/src/main/java/org/javacore/io/SFileOutputStream.java new file mode 100644 index 0000000..b88aa99 --- /dev/null +++ b/src/main/java/org/javacore/io/SFileOutputStream.java @@ -0,0 +1,206 @@ +//package org.javacore.io; +// +//import java.io.File; +//import java.io.FileDescriptor; +//import java.io.FileNotFoundException; +//import java.io.IOException; +//import java.io.OutputStream; +//import java.nio.channels.FileChannel; +// +//import sun.misc.IoTrace; +//import sun.nio.ch.FileChannelImpl; +// +///** +// * 文件输入流是用于将数据写入文件或者文件描述符类 +// * 比如写入图片等的原始字节流。如果写入字符流,考虑使用 FiLeWriter。 +// */ +//public class SFileOutputStream extends OutputStream +//{ +// /* 文件描述符类---此处用于打开文件的句柄 */ +// private final FileDescriptor fd; +// +// /* 引用文件的路径 */ +// private final String path; +// +// /* 如果为 true,则将字节写入文件末尾处,而不是写入文件开始处 */ +// private final boolean append; +// +// /* 关联的FileChannel类,懒加载 */ +// private FileChannel channel; +// +// private final Object closeLock = new Object(); +// private volatile boolean closed = false; +// private static final ThreadLocal runningFinalize =
+// new ThreadLocal();
+//
+// private static boolean isRunningFinalize() {
+// Boolean val;
+// if ((val = runningFinalize.get()) != null)
+// return val.booleanValue();
+// return false;
+// }
+//
+// /* 通过文件名创建文件输入流 */
+// public FileOutputStream(String name) throws FileNotFoundException {
+// this(name != null ? new File(name) : null, false);
+// }
+//
+// /* 通过文件名创建文件输入流,并确定文件写入起始处模式 */
+// public FileOutputStream(String name, boolean append)
+// throws FileNotFoundException
+// {
+// this(name != null ? new File(name) : null, append);
+// }
+//
+// /* 通过文件创建文件输入流,默认写入文件的开始处 */
+// public FileOutputStream(File file) throws FileNotFoundException {
+// this(file, false);
+// }
+//
+// /* 通过文件创建文件输入流,并确定文件写入起始处 */
+// public FileOutputStream(File file, boolean append)
+// throws FileNotFoundException
+// {
+// String name = (file != null ? file.getPath() : null);
+// SecurityManager security = System.getSecurityManager();
+// if (security != null) {
+// security.checkWrite(name);
+// }
+// if (name == null) {
+// throw new NullPointerException();
+// }
+// if (file.isInvalid()) {
+// throw new FileNotFoundException("Invalid file path");
+// }
+// this.fd = new FileDescriptor();
+// this.append = append;
+// this.path = name;
+// fd.incrementAndGetUseCount();
+// open(name, append);
+// }
+//
+// /* 通过文件描述符类创建文件输入流 */
+// public FileOutputStream(FileDescriptor fdObj) {
+// SecurityManager security = System.getSecurityManager();
+// if (fdObj == null) {
+// throw new NullPointerException();
+// }
+// if (security != null) {
+// security.checkWrite(fdObj);
+// }
+// this.fd = fdObj;
+// this.path = null;
+// this.append = false;
+//
+// fd.incrementAndGetUseCount();
+// }
+//
+// /* 打开文件,并确定文件写入起始处模式 */
+// private native void open(String name, boolean append)
+// throws FileNotFoundException;
+//
+// /* 将指定的字节b写入到该文件输入流,并指定文件写入起始处模式 */
+// private native void write(int b, boolean append) throws IOException;
+//
+// /* 将指定的字节b写入到该文件输入流 */
+// public void write(int b) throws IOException {
+// Object traceContext = IoTrace.fileWriteBegin(path);
+// int bytesWritten = 0;
+// try {
+// write(b, append);
+// bytesWritten = 1;
+// } finally {
+// IoTrace.fileWriteEnd(traceContext, bytesWritten);
+// }
+// }
+//
+// /* 将指定的字节数组写入该文件输入流,并指定文件写入起始处模式 */
+// private native void writeBytes(byte b[], int off, int len, boolean append)
+// throws IOException;
+//
+// /* 将指定的字节数组b写入该文件输入流 */
+// public void write(byte b[]) throws IOException {
+// Object traceContext = IoTrace.fileWriteBegin(path);
+// int bytesWritten = 0;
+// try {
+// writeBytes(b, 0, b.length, append);
+// bytesWritten = b.length;
+// } finally {
+// IoTrace.fileWriteEnd(traceContext, bytesWritten);
+// }
+// }
+//
+// /* 将指定len长度的字节数组b写入该文件输入流 */
+// public void write(byte b[], int off, int len) throws IOException {
+// Object traceContext = IoTrace.fileWriteBegin(path);
+// int bytesWritten = 0;
+// try {
+// writeBytes(b, off, len, append);
+// bytesWritten = len;
+// } finally {
+// IoTrace.fileWriteEnd(traceContext, bytesWritten);
+// }
+// }
+//
+// /* 关闭此文件输出流并释放与此流有关的所有系统资源 */
+// public void close() throws IOException {
+// synchronized (closeLock) {
+// if (closed) {
+// return;
+// }
+// closed = true;
+// }
+//
+// if (channel != null) {
+// fd.decrementAndGetUseCount();
+// channel.close();
+// }
+//
+// int useCount = fd.decrementAndGetUseCount();
+//
+// if ((useCount <= 0) || !isRunningFinalize()) { +// close0(); +// } +// } +// +// public final FileDescriptor getFD() throws IOException { +// if (fd != null) return fd; +// throw new IOException(); +// } +// +// public FileChannel getChannel() { +// synchronized (this) { +// if (channel == null) { +// channel = FileChannelImpl.open(fd, path, false, true, append, this); +// +// fd.incrementAndGetUseCount(); +// } +// return channel; +// } +// } +// +// protected void finalize() throws IOException { +// if (fd != null) { +// if (fd == FileDescriptor.out || fd == FileDescriptor.err) { +// flush(); +// } else { +// +// runningFinalize.set(Boolean.TRUE); +// try { +// close(); +// } finally { +// runningFinalize.set(Boolean.FALSE); +// } +// } +// } +// } +// +// private native void close0() throws IOException; +// +// private static native void initIDs(); +// +// static { +// initIDs(); +// } +// +//} \ No newline at end of file diff --git a/src/main/java/org/javacore/io/SInputStream.java b/src/main/java/org/javacore/io/SInputStream.java new file mode 100644 index 0000000..361b6f6 --- /dev/null +++ b/src/main/java/org/javacore/io/SInputStream.java @@ -0,0 +1,95 @@ +package org.javacore.io; + +import java.io.IOException; + +/** + * 所有字节输入流实现类的基类 + */ +public abstract class SInputStream { + + // 缓存区字节数组最大值 + private static final int MAX_SKIP_BUFFER_SIZE = 2048; + + // 从输入流中读取数据的下一个字节,以int返回 + public abstract int read() throws IOException; + + // 从输入流中读取数据的一定数量字节,并存储在缓存数组b + public int read(byte b[]) throws IOException { + return read(b, 0, b.length); + } + + // 从输入流中读取数据最多len个字节,并存储在缓存数组b + public int read(byte b[], int off, int len) throws IOException { + if (b == null) { + throw new NullPointerException(); + } else if (off < 0 || len < 0 || len> b.length - off) {
+ throw new IndexOutOfBoundsException();
+ } else if (len == 0) {
+ return 0;
+ }
+
+ int c = read();
+ if (c == -1) {
+ return -1;
+ }
+ b[off] = (byte)c;
+
+ int i = 1;
+ try {
+ for (; i < len ; i++) { + c = read(); + if (c == -1) { + break; + } + b[off + i] = (byte)c; + } + } catch (IOException ee) { + } + return i; + } + + // 跳过输入流中数据的n个字节 + public long skip(long n) throws IOException { + + long remaining = n; + int nr; + + if (n <= 0) { + return 0; + } + + int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining); + byte[] skipBuffer = new byte[size]; + while (remaining> 0) {
+ nr = read(skipBuffer, 0, (int)Math.min(size, remaining));
+ if (nr < 0) { + break; + } + remaining -= nr; + } + + return n - remaining; + } + + // 返回下一个方法调用能不受阻塞地从此读取(或者跳过)的估计字节数 + public int available() throws IOException { + return 0; + } + + // 关闭此输入流,并释放与其关联的所有资源 + public void close() throws IOException {} + + // 在此输出流中标记当前位置 + public synchronized void mark(int readlimit) {} + + // 将此流重新定位到最后一次对此输入流调用 mark 方法时的位置。 + public synchronized void reset() throws IOException { + throw new IOException("mark/reset not supported"); + } + + // 测试此输入流是否支持 mark 和 reset 方法 + public boolean markSupported() { + return false; + } + +} diff --git a/src/main/java/org/javacore/io/SOutputStream.java b/src/main/java/org/javacore/io/SOutputStream.java new file mode 100644 index 0000000..c254818 --- /dev/null +++ b/src/main/java/org/javacore/io/SOutputStream.java @@ -0,0 +1,43 @@ +package org.javacore.io; + +import java.io.Closeable; +import java.io.Flushable; +import java.io.IOException; + +/** + * 所有字节输出流实现类的基类 + */ +public abstract class SOutputStream implements Closeable, Flushable { + + // 将指定的字节写入输出流 + public abstract void write(int b) throws IOException; + + // 将指定的byte数组的字节全部写入输出流 + public void write(byte b[]) throws IOException { + write(b, 0, b.length); + } + + // 将指定的byte数组中从偏移量off开始的len个字节写入输出流 + public void write(byte b[], int off, int len) throws IOException { + if (b == null) { + throw new NullPointerException(); + } else if ((off < 0) || (off> b.length) || (len < 0) || + ((off + len)> b.length) || ((off + len) < 0)) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return; + } + for (int i = 0 ; i < len ; i++) { + write(b[off + i]); + } + } + + // 刷新输出流,并强制写出所有缓冲的输出字节 + public void flush() throws IOException { + } + + // 关闭输出流,并释放与该流有关的所有资源 + public void close() throws IOException { + } + +} \ No newline at end of file diff --git a/src/main/java/org/javacore/io/StoringAndRecoveringData.java b/src/main/java/org/javacore/io/StoringAndRecoveringData.java new file mode 100644 index 0000000..9773592 --- /dev/null +++ b/src/main/java/org/javacore/io/StoringAndRecoveringData.java @@ -0,0 +1,51 @@ +package org.javacore.io; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-9-28 17:30:21 + * DataOutputStream和DataInputStream的使用案例 + */ +public class StoringAndRecoveringData { + + @SuppressWarnings("resource") + public static void main(String[] args) throws IOException { + // 写入数据 + DataOutputStream outputStream = new DataOutputStream( + new BufferedOutputStream(new FileOutputStream("data.txt"))); + outputStream.writeDouble(3.1415926); + outputStream.writeUTF("你好"); + outputStream.writeInt(1); + outputStream.close(); + + // 写出数据 + DataInputStream inputStream = new DataInputStream( + new BufferedInputStream(new FileInputStream("data.txt"))); + System.out.println(inputStream.readDouble()); + System.out.println(inputStream.readUTF()); + System.out.println(inputStream.readInt()); + } +} diff --git a/src/org/javacore/io/SystemStreamT.java b/src/main/java/org/javacore/io/SystemStreamT.java similarity index 100% rename from src/org/javacore/io/SystemStreamT.java rename to src/main/java/org/javacore/io/SystemStreamT.java diff --git a/src/main/java/org/javacore/io/TextFile.java b/src/main/java/org/javacore/io/TextFile.java new file mode 100644 index 0000000..bffa307 --- /dev/null +++ b/src/main/java/org/javacore/io/TextFile.java @@ -0,0 +1,120 @@ +package org.javacore.io; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.TreeSet; + +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-9-30 16:10:18 + * 文本文件的操作案例 + */ +public class TextFile extends ArrayList {
+
+ private static final long serialVersionUID = -6710557138987846943L;
+
+ // 读取文件内容,返回内容字符串
+ public static String read(String fileName) {
+ StringBuilder sb = new StringBuilder();
+ try {
+ // 创建缓存字符输入流
+ BufferedReader in = new BufferedReader(new FileReader(// 创建读取字符文件类
+ new File(fileName).getAbsolutePath()));// 文件绝对路径地址
+ try {
+ String s;
+ // 读取一个文本行
+ while ((s = in.readLine()) != null) {
+ sb.append(s);
+ sb.append("\n");
+ }
+ } finally {
+ in.close();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return sb.toString();
+ }
+
+ // 将字符串写入一个文本文件
+ public static void write(String fileName,String text) {
+ try {
+ // 创建打印输出流
+ PrintWriter out = new PrintWriter(
+ new File(fileName).getAbsolutePath());
+ try {
+ // 写入字符流
+ out.write(text);
+ } finally {
+ out.close();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ // 通过正则匹配,读取文件
+ public TextFile(String fileName,String splitter) {
+ super(Arrays.asList(read(fileName).split(splitter)));
+ // 移除一个空格位置
+ if (get(0).equals("")) remove(0);
+ }
+
+ public TextFile(String fileName) {
+ this(fileName, "\n");
+ }
+
+ // 写入一个文本文件
+ public void write(String fileName) {
+ try {
+ // 创建打印输出流
+ PrintWriter out = new PrintWriter(
+ new File(fileName).getAbsolutePath());
+ try {
+ for (String item : this)
+ out.write(item);
+ } finally {
+ out.close();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ public static void main(String[] args) {
+ // 读取文件
+ String file = read("src/org/javacore/io/TextFile.java");
+ // 写入到test.txt
+ write("test.txt", file);
+
+ TextFile text = new TextFile("test.txt");
+ text.write("test2.txt");
+
+ TreeSet words = new TreeSet(
+ new TextFile("src/org/javacore/io/TextFile.java","\\W+"));
+ System.out.println(words.headSet("a"));
+
+ }
+}
diff --git a/src/main/java/org/javacore/io/UsingRandomAccessFile.java b/src/main/java/org/javacore/io/UsingRandomAccessFile.java
new file mode 100644
index 0000000..2f78e42
--- /dev/null
+++ b/src/main/java/org/javacore/io/UsingRandomAccessFile.java
@@ -0,0 +1,57 @@
+package org.javacore.io;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年9月28日 18:50:22
+ * RandomAccessFile的使用案例
+ */
+public class UsingRandomAccessFile {
+ // 文件名
+ static String file = "rtest.bat";
+
+ static void display() throws IOException {
+ // 创建随机访问类,只读模式
+ RandomAccessFile rf = new RandomAccessFile(file, "r");
+ for (int i = 0; i < 7; i++) + System.out.println("Value " + i + ": " + rf.readDouble());// 读取一个Double + System.out.println(rf.readUTF());// 读取一个字符串 + rf.close(); + } + + public static void main(String[] args) throws IOException { + // 创建随机访问类,读写模式 + RandomAccessFile rf = new RandomAccessFile(file, "rw"); + for (int i = 0; i < 7; i++) + rf.writeDouble( i * 1.123);// 写入一个Double + rf.writeUTF("文件结束");// 写入一个字符串 + rf.close(); + + display(); + + rf = new RandomAccessFile(file, "rw"); + rf.seek(5 * 8);// 设置文件指针偏移量,设置到第5个双精度字节 + rf.writeDouble(47.003); + rf.close(); + + display(); + } +} diff --git a/src/org/javacore/io/byteoper/IntegerConvertT.java b/src/main/java/org/javacore/io/byteoper/IntegerConvertT.java similarity index 100% rename from src/org/javacore/io/byteoper/IntegerConvertT.java rename to src/main/java/org/javacore/io/byteoper/IntegerConvertT.java diff --git a/src/org/javacore/io/byteoper/IntegerOperT.java b/src/main/java/org/javacore/io/byteoper/IntegerOperT.java similarity index 100% rename from src/org/javacore/io/byteoper/IntegerOperT.java rename to src/main/java/org/javacore/io/byteoper/IntegerOperT.java diff --git a/src/org/javacore/io/byteoper/LongConvertT.java b/src/main/java/org/javacore/io/byteoper/LongConvertT.java similarity index 100% rename from src/org/javacore/io/byteoper/LongConvertT.java rename to src/main/java/org/javacore/io/byteoper/LongConvertT.java diff --git a/src/org/javacore/io/byteoper/StringConvertT.java b/src/main/java/org/javacore/io/byteoper/StringConvertT.java similarity index 78% rename from src/org/javacore/io/byteoper/StringConvertT.java rename to src/main/java/org/javacore/io/byteoper/StringConvertT.java index a8189f8..b732f61 100644 --- a/src/org/javacore/io/byteoper/StringConvertT.java +++ b/src/main/java/org/javacore/io/byteoper/StringConvertT.java @@ -5,9 +5,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -23,11 +23,12 @@ public class StringConvertT { public static void main(String[] args){ - String str = "李强强"; + String str = "HOME"; byte[] bytes = str.getBytes(); // 打印字节数组 - System.out.println("UTF-8编码'李强强'的字节数组为:"); - for (int i = 0; i < bytes.length; i++) - System.out.print("\t" + bytes[i]); + System.out.println("UTF-8编码'HOME'的字节数组为:"); + for (int i = 0; i < bytes.length; i++) { + System.out.println("\t" + bytes[i] + "|" + Integer.toBinaryString(bytes[i])); + } } } diff --git a/src/main/java/org/javacore/io/serializable/SerializableT.java b/src/main/java/org/javacore/io/serializable/SerializableT.java new file mode 100644 index 0000000..32c9197 --- /dev/null +++ b/src/main/java/org/javacore/io/serializable/SerializableT.java @@ -0,0 +1,60 @@ +package org.javacore.io.serializable; + + +//import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream; +// +//import java.io.*; +// +///** +// * 描述:Java序列化和反序列化的小例子 +// * Created by 子木 on 2016/2/15. +// */ +//public class SerializableT { +// public static void main(String[] args) throws IOException, ClassNotFoundException { +// for (int i = 0;i < 10;i++) { +// AObjcet aObjcet = new AObjcet(); +// long beginTime = System.currentTimeMillis(); +// +// ByteOutputStream byteOutput = new ByteOutputStream(); +// ObjectOutputStream objectOutput = new ObjectOutputStream(byteOutput); +// objectOutput.writeObject(aObjcet); +// objectOutput.close(); +// byteOutput.close(); +// byte[] bytes = byteOutput.toByteArray(); +// System.out.println("Java序列化耗时:" + (System.currentTimeMillis() - beginTime) + "ms"); +// System.out.println("Java序列化后的字节大小为:" + bytes.length); +// +// beginTime = System.currentTimeMillis(); +// ByteArrayInputStream byteInput = new ByteArrayInputStream(bytes); +// ObjectInputStream objectInput = new ObjectInputStream(byteInput); +// objectInput.readObject(); +// objectInput.close(); +// byteInput.close(); +// System.out.println("Java反序列化耗时:" + (System.currentTimeMillis() - beginTime) + "ms"); +// +// } +// } +//} +//class AObjcet implements Serializable { +// private String a = "bysocket"; +// private String b = "likes"; +// private String c = "java"; +// private String d = "world"; +// +// private int i = 100; +// private int j = 10; +// private long m = 100L; +// +// private boolean isA = true; +// private boolean isB = false; +// private boolean isC = false; +// +// private BObject aObject = new BObject(); +// private BObject bObject = new BObject(); +// private BObject cObject = new BObject(); +// private BObject dObject = new BObject(); +// +//} +//class BObject implements Serializable { +// +//} diff --git a/src/main/java/org/javacore/io/zip/GZIPcompress.java b/src/main/java/org/javacore/io/zip/GZIPcompress.java new file mode 100644 index 0000000..b446c58 --- /dev/null +++ b/src/main/java/org/javacore/io/zip/GZIPcompress.java @@ -0,0 +1,60 @@ +package org.javacore.io.zip; + +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-10-17 13:59:25 + * GZIP简单使用 + */ +public class GZIPcompress { + public static void main(String[] args) throws IOException { + // 用Reader读文件 + BufferedReader in = new BufferedReader(new InputStreamReader( + new FileInputStream("data.gz" ), "UTF-8" )); + // 使用缓冲输出流,输出压缩流文件 + BufferedOutputStream out = new BufferedOutputStream( + new GZIPOutputStream(new FileOutputStream("data.gz"))); + System.out.println("Writing File 压缩"); + int c; + while ((c = in.read())> 0)
+ out.write(String.valueOf((char)c).getBytes("UTF-8"));
+ in.close();
+ out.close();
+
+ System.out.println("Reading File 解压");
+ // 用输入解压流读取文件
+ BufferedReader in2 = new BufferedReader(
+ new InputStreamReader(
+ new GZIPInputStream(new FileInputStream("data.gz")),"UTF-8"));// encoding question
+ String s;
+ while ((s=in2.readLine()) != null)
+ System.out.println(s);
+ in2.close();
+ }
+}
diff --git a/src/main/java/org/javacore/io/zip/ZipCompress.java b/src/main/java/org/javacore/io/zip/ZipCompress.java
new file mode 100644
index 0000000..d0a6e61
--- /dev/null
+++ b/src/main/java/org/javacore/io/zip/ZipCompress.java
@@ -0,0 +1,120 @@
+package org.javacore.io.zip;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.zip.Adler32;
+import java.util.zip.CheckedInputStream;
+import java.util.zip.CheckedOutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年10月17日 14:58:59
+ * 利用Zip进行多文件保存
+ */
+public class ZipCompress {
+ private static String filePath = "src" + File.separator +
+ "org" + File.separator +
+ "javacore" + File.separator +
+ "io" + File.separator;
+
+ private static String[] fileNames= new String[] {
+ filePath + "BufferedInputFileT.java",
+ filePath + "ChangeSystemOut.java"
+ };
+
+ public static void main(String[] args) throws IOException {
+ zipFiles(fileNames);
+ }
+
+ private static void zipFiles(String[] fileNames)
+ throws IOException {
+ // 获取zip文件输出流
+ FileOutputStream f = new FileOutputStream("test.zip");
+ // 从文件输出流中获取数据校验和输出流,并设置Adler32
+ CheckedOutputStream csum = new CheckedOutputStream(f,new Adler32());
+ // 从数据校验和输出流中获取Zip输出流
+ ZipOutputStream zos = new ZipOutputStream(csum);
+ // 从Zip输出流中获取缓冲输出流
+ BufferedOutputStream out = new BufferedOutputStream(zos);
+ // 设置Zip文件注释
+ zos.setComment("测试 java zip stream");
+ for (String file : fileNames) {
+ System.out.println("写入文件: " + file);
+ // 获取文件输入字符流
+ BufferedReader in =
+ new BufferedReader(new FileReader(file));
+ // 想Zip处理写入新的文件条目,并流定位到数据开始处
+ zos.putNextEntry(new ZipEntry(file));
+ int c;
+ while ((c = in.read())> 0)
+ out.write(c);
+ in.close();
+ // 刷新Zip输出流,将缓冲的流写入该流
+ out.flush();
+ }
+ // 文件全部写入Zip输出流后,关闭
+ out.close();
+
+ // 输出数据校验和
+ System.out.println("数据校验和: " + csum.getChecksum().getValue());
+ System.out.println("读取zip文件");
+ // 读取test.zip文件输入流
+ FileInputStream fi = new FileInputStream("test.zip");
+ // 从文件输入流中获取数据校验和流
+ CheckedInputStream csumi = new CheckedInputStream(fi,new Adler32());
+ // 从数据校验和流中获取Zip解压流
+ ZipInputStream in2 = new ZipInputStream(csumi);
+ // 从Zip解压流中获取缓冲输入流
+ BufferedInputStream bis = new BufferedInputStream(in2);
+ // 创建文件条目
+ ZipEntry zipEntry;
+ while ((zipEntry = in2.getNextEntry()) != null) {
+ System.out.println("读取文件: " + zipEntry);
+ int x;
+ while ((x = bis.read())> 0)
+ System.out.write(x);
+ }
+ if (fileNames.length == 1)
+ System.out.println("数据校验和: " + csumi.getChecksum().getValue());
+ bis.close();
+
+ // 获取Zip文件
+ ZipFile zf = new ZipFile("test.zip");
+ // 获取文件条目枚举
+ Enumeration e = zf.entries();
+ while (e.hasMoreElements()) {
+ // 从Zip文件的枚举中获取文件条目
+ ZipEntry ze2 = (ZipEntry) e.nextElement();
+ System.out.println("文件: " + ze2);
+ }
+
+ }
+}
diff --git a/src/main/java/org/javacore/lambda/LambdaListCompare.java b/src/main/java/org/javacore/lambda/LambdaListCompare.java
new file mode 100644
index 0000000..1afc67f
--- /dev/null
+++ b/src/main/java/org/javacore/lambda/LambdaListCompare.java
@@ -0,0 +1,59 @@
+package org.javacore.lambda;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * List 比较器
+ *
+ * Created by bysocket on 16/7/12.
+ */
+public class LambdaListCompare {
+ public static void main(String[] args) {
+ List list = new ArrayList();
+ list.add(4);
+ list.add(1);
+ list.add(3);
+ list.add(6);
+
+// list.sort(new Comparator() {
+// @Override
+// public int compare(Integer o1, Integer o2) {
+// return Integer.compare(o1, o2);
+// }
+// });
+
+ /** Lambda表达式格式:
+ * (Type1 param1, Type2 param2, ..., TypeN paramN) -> {
+ * statment1;
+ * statment2;
+ * ...
+ * return statmentM;
+ * }
+ */
+// list.sort(((o1, o2) -> {
+// return Integer.compare(o1, o2);
+// }));
+
+ // 简写Lambda表达式
+ list.sort((o1, o2) -> Integer.compare(o1, o2));
+
+ System.out.println(list.toString());
+ }
+}
diff --git a/src/main/java/org/javacore/lambda/LambdaOperators.java b/src/main/java/org/javacore/lambda/LambdaOperators.java
new file mode 100644
index 0000000..85dfde1
--- /dev/null
+++ b/src/main/java/org/javacore/lambda/LambdaOperators.java
@@ -0,0 +1,51 @@
+package org.javacore.lambda;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * Lambda 操作符
+ *
+ * Created by bysocket on 16/7/13.
+ */
+public class LambdaOperators {
+ public static void main(String[] args) {
+ List list = new ArrayList();
+ list.add("aaa");
+ list.add("cccc");
+ list.add("b");
+ list.add("eeeee");
+
+ /**
+ * :: 操作符格式 => 三种情况
+ * 对象::实例方法
+ * 类::静态方法
+ * 类::实例方法 对于前两种情况,方法引用就是对参数执行该方法。比如下面两种方法
+ */
+ // 按字符串大小排序忽略大小写
+ list.sort(String::compareToIgnoreCase);
+ // 打印 list 元素
+ list.forEach(System.out::println);
+
+ System.out.println("======按字符大小排序======");
+ list.sort(Comparator.comparing(String::length));
+ list.forEach(System.out::println);
+ }
+}
diff --git a/src/main/java/org/javacore/lambda/LambdaRunnable.java b/src/main/java/org/javacore/lambda/LambdaRunnable.java
new file mode 100644
index 0000000..9cf408a
--- /dev/null
+++ b/src/main/java/org/javacore/lambda/LambdaRunnable.java
@@ -0,0 +1,45 @@
+package org.javacore.lambda;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Lambda - 启动线程
+ *
+ * Created by bysocket on 16/7/13.
+ */
+public class LambdaRunnable {
+ static int b = 10;
+
+ public static void main(String[] args) {
+ // 启动线程
+// Thread thread = new Thread(new Runnable() {
+// @Override
+// public void run() {
+// b++;
+// System.out.println(b);
+// }
+// });
+
+ // Lambda - 启动线程
+ Thread thread = new Thread(() -> {
+ b++;
+ System.out.println(b);
+ });
+ thread.start();
+ System.out.println("Done!");
+ }
+}
diff --git a/src/main/java/org/javacore/nio/AvailableCharSets.java b/src/main/java/org/javacore/nio/AvailableCharSets.java
new file mode 100644
index 0000000..9bdb9a3
--- /dev/null
+++ b/src/main/java/org/javacore/nio/AvailableCharSets.java
@@ -0,0 +1,51 @@
+package org.javacore.nio;
+
+import java.nio.charset.Charset;
+import java.util.Iterator;
+import java.util.SortedMap;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年10月11日 19:51:10
+ * 可用的CharSet打印
+ */
+public class AvailableCharSets {
+ public static void main(String[] args) {
+ // charset对象的有序映射
+ SortedMap charSets =
+ Charset.availableCharsets();
+ // 获取key的迭代器
+ Iterator iterator = charSets.keySet().iterator();
+ while (iterator.hasNext()) {
+ String csName = iterator.next();
+ System.out.print(csName);
+ // 获取别名的Charset集合的迭代器
+ Iterator aliases =
+ charSets.get(csName).aliases().iterator();
+ if (aliases.hasNext())
+ System.out.print(": ");
+ while (aliases.hasNext()) {
+ System.out.print(aliases.next());
+ if (aliases.hasNext())
+ System.out.print(",");
+ }
+ System.out.println();
+ }
+ }
+}
diff --git a/src/main/java/org/javacore/nio/BufferToText.java b/src/main/java/org/javacore/nio/BufferToText.java
new file mode 100644
index 0000000..7e7554d
--- /dev/null
+++ b/src/main/java/org/javacore/nio/BufferToText.java
@@ -0,0 +1,101 @@
+package org.javacore.nio;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.charset.Charset;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年10月10日 18:58:15
+ * ByteBuffer与char之间转换的案例
+ */
+public class BufferToText {
+ private static final int BSIZE = 1024; // 1K 字节
+ public static void main(String[] args) throws IOException {
+ // 从文件输出流获取FileChannel
+ FileChannel fc =
+ new FileOutputStream("data.txt").getChannel();
+ // 将带有字节的缓冲区写入该通道
+ fc.write(ByteBuffer.wrap("some data".getBytes()));
+ fc.close();
+
+ // 从文件输入流中获取FileChannel
+ fc = new FileInputStream("data.txt").getChannel();
+ // 分配ByteBuffer的大小 1K
+ ByteBuffer buffer = ByteBuffer.allocate(BSIZE);
+ // 将字节序列通过此通道写入到buffer
+ fc.read(buffer);
+ // 反转缓冲区,为写或者读取做准备
+ buffer.flip();
+ // 作为char缓冲区,并输出 乱码,因为Buffer编码是"UTF-16BE"
+ System.out.println(buffer.asCharBuffer());
+
+ // 重绕此缓冲区
+ buffer.rewind();
+ // 获取文件编码属性
+ String encoding = System.getProperty("file.encoding");
+ // 输出编码及内容
+ System.out.println("编码: " + encoding + " 内容为: "
+ + Charset.forName(encoding).decode(buffer));
+ fc.close();
+
+ // 从文件输出流获取FileChannel
+ fc = new FileOutputStream("data.txt").getChannel();
+ // 将带有字节的缓冲区写入该通道
+ fc.write(ByteBuffer.wrap("some data".getBytes("UTF-16BE")));
+ fc.close();
+
+ // 从文件输入流中获取FileChannel
+ fc = new FileInputStream("data.txt").getChannel();
+ // 清除其缓冲区
+ buffer.clear();
+ // 将字节序列通过该通道写入到buffer
+ fc.read(buffer);
+ // 反转缓冲区,为写或者读取做准备
+ buffer.flip();
+ // 作为char缓冲区,并输出
+ System.out.println(buffer.asCharBuffer());
+ fc.close();
+
+ // 从文件输出流获取FileChannel
+ fc = new FileOutputStream("data.txt").getChannel();
+ // 指定buffer大小为 24字节
+ buffer = ByteBuffer.allocate(24);
+ // 通过char缓冲区,在当前位置写入字符
+ buffer.asCharBuffer().put("some data");
+ // 将带有字节的缓冲区写入该通道
+ fc.write(buffer);
+ fc.close();
+
+ // 从文件输入流中获取FileChannel
+ fc = new FileInputStream("data.txt").getChannel();
+ // 清除缓冲区
+ buffer.clear();
+ // 将字节序列通过文件通道写入到buffer
+ fc.read(buffer);
+ // 反转缓冲区,为读或者写做准备
+ buffer.flip();
+ // 作为char缓冲区,并输出
+ System.out.println(buffer.asCharBuffer());
+ }
+}
diff --git a/src/main/java/org/javacore/nio/ChannelCopy.java b/src/main/java/org/javacore/nio/ChannelCopy.java
new file mode 100644
index 0000000..a6a1685
--- /dev/null
+++ b/src/main/java/org/javacore/nio/ChannelCopy.java
@@ -0,0 +1,63 @@
+package org.javacore.nio;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年10月9日 17:38:08
+ * FileChannel的文件复制案例
+ */
+public class ChannelCopy {
+ // 读取的文件
+ private static final String sourceFile =
+ "src" + File.separator +
+ "org" + File.separator +
+ "javacore" + File.separator +
+ "nio" + File.separator +
+ "ChannelCopy.java";
+ // 输出的文件
+ private static final String targetFile = "data.txt";
+
+ private static final int BSIZE = 1024; // 1K字节
+
+ @SuppressWarnings("resource")
+ public static void main(String[] args) throws IOException {
+ // 创建用于读写的Channel
+ FileChannel
+ in = new FileInputStream(sourceFile).getChannel(),
+ out = new FileOutputStream(targetFile).getChannel();
+
+ // 分配ByteBuffer的大小 1K
+ ByteBuffer buffer = ByteBuffer.allocate(BSIZE);
+ // 将字节序列从此通道读入给定的缓冲区,分块读,直至读到文件末端
+ while (in.read(buffer) != -1) {// -1,表示读到文件末端
+ // 反转缓冲区,为写入或读取做好准备
+ buffer.flip();
+ // 将含有字节序列的缓冲区写入文件通道
+ out.write(buffer);
+ // 清空缓冲区
+ buffer.clear();
+ }
+
+ }
+}
diff --git a/src/main/java/org/javacore/nio/Endians.java b/src/main/java/org/javacore/nio/Endians.java
new file mode 100644
index 0000000..712e77b
--- /dev/null
+++ b/src/main/java/org/javacore/nio/Endians.java
@@ -0,0 +1,50 @@
+package org.javacore.nio;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Arrays;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年10月13日 20:40:00
+ * ByteBuffer中字节存储次序
+ */
+public class Endians {
+ public static void main(String[] args) {
+ // 创建12个字节的字节缓冲区
+ ByteBuffer bb = ByteBuffer.wrap(new byte[12]);
+ // 存入字符串
+ bb.asCharBuffer().put("abdcef");
+ System.out.println(Arrays.toString(bb.array()));
+
+ // 反转缓冲区
+ bb.rewind();
+ // 设置字节存储次序
+ bb.order(ByteOrder.BIG_ENDIAN);
+ bb.asCharBuffer().put("abcdef");
+ System.out.println(Arrays.toString(bb.array()));
+
+ // 反转缓冲区
+ bb.rewind();
+ // 设置字节存储次序
+ bb.order(ByteOrder.LITTLE_ENDIAN);
+ bb.asCharBuffer().put("abcdef");
+ System.out.println(Arrays.toString(bb.array()));
+ }
+}
diff --git a/src/org/javacore/nio/FileChannelT.java b/src/main/java/org/javacore/nio/FileChannelT.java
similarity index 100%
rename from src/org/javacore/nio/FileChannelT.java
rename to src/main/java/org/javacore/nio/FileChannelT.java
diff --git a/src/main/java/org/javacore/nio/FileChannelTransferTo.java b/src/main/java/org/javacore/nio/FileChannelTransferTo.java
new file mode 100644
index 0000000..d480afc
--- /dev/null
+++ b/src/main/java/org/javacore/nio/FileChannelTransferTo.java
@@ -0,0 +1,53 @@
+package org.javacore.nio;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年10月9日 17:43:27
+ * FileChannel的transferTo/transferFrom案例
+ */
+public class FileChannelTransferTo {
+ // 读取的文件
+ private static final String sourceFile =
+ "src" + File.separator +
+ "org" + File.separator +
+ "javacore" + File.separator +
+ "nio" + File.separator +
+ "FileChannelTransferTo.java";
+ // 输出的文件
+ private static final String targetFile = "data.txt";
+
+ @SuppressWarnings("resource")
+ public static void main(String[] args) throws IOException {
+ // 创建用于读写的Channel
+ FileChannel
+ in = new FileInputStream(sourceFile).getChannel(),
+ out = new FileOutputStream(targetFile).getChannel();
+ // 将in通道的字节传输给out可写入字节通道
+ in.transferTo(0, in.size(),out);
+ // or
+ // 将字节从给定的可读取字节通道传输到此通道的文件中。
+ // out.transferFrom(in, 0, in.size());
+ }
+}
diff --git a/src/main/java/org/javacore/nio/FileLocking.java b/src/main/java/org/javacore/nio/FileLocking.java
new file mode 100644
index 0000000..3e86898
--- /dev/null
+++ b/src/main/java/org/javacore/nio/FileLocking.java
@@ -0,0 +1,44 @@
+package org.javacore.nio;
+
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.channels.FileLock;
+import java.util.concurrent.TimeUnit;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年10月15日 19:31:34
+ * 文件加锁
+ */
+public class FileLocking {
+ public static void main(String[] args) throws IOException, InterruptedException {
+ // 获取输出流
+ FileOutputStream fos = new FileOutputStream("data.txt");
+ // 从输出流中获取文件加锁对象,并锁定File
+ FileLock fl = fos.getChannel().lock();
+ if (fl != null) {
+ System.out.println("Locked File");
+ TimeUnit.MICROSECONDS.sleep(100);
+ // 释放文件锁定
+ fl.release();
+ System.out.println("Release Lock");
+ }
+ }
+}
diff --git a/src/main/java/org/javacore/nio/GetChannel.java b/src/main/java/org/javacore/nio/GetChannel.java
new file mode 100644
index 0000000..61c2f65
--- /dev/null
+++ b/src/main/java/org/javacore/nio/GetChannel.java
@@ -0,0 +1,75 @@
+package org.javacore.nio;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年10月8日 17:33:19
+ * 从流中获取FileChannel的案例
+ */
+public class GetChannel {
+ private static final int BSIZE = 1024; // 1K字节
+
+ @SuppressWarnings("resource")
+ public static void main(String[] args) throws IOException {
+ //////
+ // 写入文件
+ //////
+ // 从文件输出流获取FileChannel
+ FileChannel fc = new FileOutputStream("data.txt").getChannel();
+ // 将含有字节序列的缓冲区写入文件通道
+ fc.write(ByteBuffer.wrap("Some Text".getBytes()));// 将已存在的字节数组包装到ByteBuffer
+ // 关闭通道
+ fc.close();
+
+ //////
+ // 从文件尾部写入
+ //////
+ // 从RandomAccessFile获取FileChannel文件
+ fc = new RandomAccessFile("data.txt", "rw").getChannel();
+ // 文件指针指向文件尾部
+ fc.position(fc.size());
+ // 将含有字节序列的缓冲区写入文件通道
+ fc.write(ByteBuffer.wrap(" Some more".getBytes()));
+ // 关闭通道
+ fc.close();
+
+ //////
+ // 读取文件
+ //////
+ // 从文件输出流获取FileChannel文件
+ fc = new FileInputStream("data.txt").getChannel();
+ // 分配ByteBuffer的大小 1K
+ ByteBuffer buffer = ByteBuffer.allocate(BSIZE);
+ // 将字节序列从此通道读入给定的缓冲区。
+ fc.read(buffer);
+ // 反转缓冲区,为写入或读取做好准备
+ buffer.flip();
+ // 打印
+ while (buffer.hasRemaining()) {
+ System.out.print((char)buffer.get());
+ }
+ }
+
+}
diff --git a/src/main/java/org/javacore/nio/GetData.java b/src/main/java/org/javacore/nio/GetData.java
new file mode 100644
index 0000000..0a4766e
--- /dev/null
+++ b/src/main/java/org/javacore/nio/GetData.java
@@ -0,0 +1,60 @@
+package org.javacore.nio;
+
+import java.nio.ByteBuffer;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年10月12日 18:53:10
+ * ByteBuffer操作类型数据的案例
+ */
+public class GetData {
+ private static final int BSIZE = 1024; // 1字节
+ public static void main(String[] args) {
+ // 创建字节缓冲区
+ ByteBuffer bb = ByteBuffer.allocate(BSIZE);
+ int i = 0;
+ while (i++ < bb.limit())// 缓冲区的限制 + if (bb.get() != 0)// 读取当前位置字节,如果字节不等于0 + System.out.println("该字节不为0"); + // 读取到最后一个跳出限制while,i为BSIZE大1。 + System.out.println("i = " + i); + + // 重绕此缓冲区 + bb.rewind(); + // 写入Hello + bb.asCharBuffer().put("Hello"); + // 从缓冲区读取char,并输出 + char c; + while ((c = bb.getChar()) != 0) + System.out.print(c + " "); + System.out.println(); + + // 写入Short类型数据 + bb.asShortBuffer().put((short) 47142); + System.out.println(bb.getShort()); + // 重绕此缓冲区 + bb.rewind(); + + // 写入Long类型数据 + bb.asLongBuffer().put((long)99471142); + System.out.println(bb.getLong()); + // 重绕此缓冲区 + bb.rewind(); + } +} diff --git a/src/main/java/org/javacore/nio/IntBufferDemo.java b/src/main/java/org/javacore/nio/IntBufferDemo.java new file mode 100644 index 0000000..2736e3d --- /dev/null +++ b/src/main/java/org/javacore/nio/IntBufferDemo.java @@ -0,0 +1,49 @@ +package org.javacore.nio; + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; + +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-10-12 18:53:01 + * 通过IntBuffer操作ByteBuffer的int型数据 + */ +public class IntBufferDemo { + private static final int BSIZE = 1024;// 1字节 + public static void main(String[] args) { + // 创建1字节大小的字节缓冲区 + ByteBuffer bb = ByteBuffer.allocate(BSIZE); + // int视图缓冲区 + IntBuffer ib = bb.asIntBuffer(); + // 存储一个数组 + ib.put(new int[]{1, 2, 3, 4, 5, 6}); + // 通过访问ByteBuff字节缓冲区,获取某个位置的值 + System.out.println(ib.get(3)); + // 存储一个int数据 + ib.put(3, 44); + // 反转缓冲区 + ib.flip(); + // 如果当前位置还有元素 + while (ib.hasRemaining()) { + // 获取当前位置的元素 + int i = ib.get(); + System.out.println(i); + } + } +} diff --git a/src/main/java/org/javacore/nio/LargeMappedFiles.java b/src/main/java/org/javacore/nio/LargeMappedFiles.java new file mode 100644 index 0000000..72cd8fb --- /dev/null +++ b/src/main/java/org/javacore/nio/LargeMappedFiles.java @@ -0,0 +1,45 @@ +package org.javacore.nio; + +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; + +/** + * @author Jeff Lee + * @since 2015-10-14 16:01:14 + * 内存映射文件的使用 + */ +public class LargeMappedFiles { + static int length = 0x8FFFFFF; // 128 MB + + public static void main(String[] args) throws IOException { + // 将此通道的文件区域直接映射到内存映射区域中。 + MappedByteBuffer out = new RandomAccessFile("data.txt","rw").getChannel() + .map(FileChannel.MapMode.READ_WRITE, 0, length); + // 写入128MB的字符串 + for (int i = 0;i < length; i++) + out.put((byte)'x'); + System.out.println("Finished writing"); + // 打印其中6个字符 + for (int i = length/2; i < length/2 + 6; i++) + System.out.print((char)out.get(i)); + } +} diff --git a/src/main/java/org/javacore/nio/LockingMappedFiles.java b/src/main/java/org/javacore/nio/LockingMappedFiles.java new file mode 100644 index 0000000..d0c7ace --- /dev/null +++ b/src/main/java/org/javacore/nio/LockingMappedFiles.java @@ -0,0 +1,75 @@ +package org.javacore.nio; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.channels.FileLock; + +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-10-17 15:17:04 + * 映射文件的使用 + */ +public class LockingMappedFiles { + static final int LENGTH = 0x8FFFFFF; // 128 MB + static FileChannel fc; + + public static void main(String[] args) throws IOException { + fc = new RandomAccessFile("data.txt" , "rw").getChannel(); + MappedByteBuffer out = fc.map(FileChannel.MapMode.READ_WRITE, + 0 , LENGTH); + for (int i = 0;i < LENGTH; i++) + out.put((byte)'x'); + new LockAndModify(out,0,0 + LENGTH/3); + new LockAndModify(out,LENGTH/2,LENGTH/2 + LENGTH/4); + } + + // 线程 + private static class LockAndModify extends Thread { + private ByteBuffer buffer; + private int start,end; + + LockAndModify(ByteBuffer mbb, int start, int end) { + this.start = start; + this.end = end; + mbb.limit(end); + mbb.position(start); + buffer = mbb.slice(); + start(); + } + + public void run() { + try { + // 从FileChannel获取文件加锁对象,并加锁 + FileLock fl = fc.lock(start,end,false); + System.out.println("Locked: " + start + " to " + end); + // 写入数据 + while (buffer.position() < buffer.limit() - 1) + buffer.put((byte)(buffer.get() + 1)); + fl.release(); + System.out.println("Released: " + start + " to " + end); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } +} diff --git a/src/main/java/org/javacore/nio/MappedIO.java b/src/main/java/org/javacore/nio/MappedIO.java new file mode 100644 index 0000000..83a58f1 --- /dev/null +++ b/src/main/java/org/javacore/nio/MappedIO.java @@ -0,0 +1,141 @@ +package org.javacore.nio; + +import org.javacore.io.RandomAccessFileT; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.IntBuffer; +import java.nio.channels.FileChannel; + +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-10-15 18:38:17 + * MappedByteBuffer与Old IO的性能比 + */ +public class MappedIO { + private static int numOfInts = 4000000; + private static int numOfUbuffInts = 200000; + + private abstract static class Tester { + private String name; + public Tester(String name){ + this.name = name; + } + + // 打印测试时间 + public void runTests(){ + System.out.print(name + ": "); + try { + long start = System.nanoTime(); + test(); + double duration = System.nanoTime() - start; + System.out.format("%.2f\n",duration/1.0e9); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public abstract void test() throws IOException; + } + + private static Tester[] tests = { + new Tester("Stream Write") { + @Override + public void test() throws IOException { + DataOutputStream dos = new DataOutputStream( + new BufferedOutputStream(new FileOutputStream(new File("data.txt")))); + for (int i = 0; i < numOfInts; i++) + dos.writeInt(i); + dos.close(); + } + }, + new Tester("Mapped Write") { + @Override + public void test() throws IOException { + FileChannel fc = + new RandomAccessFile("data.txt" , "rw").getChannel(); + IntBuffer ib = fc.map(FileChannel.MapMode.READ_WRITE, + 0,fc.size()).asIntBuffer(); + for (int i = 0; i < numOfInts; i++) + ib.put(i); + fc.close(); + } + }, + new Tester("Stream Read") { + @Override + public void test() throws IOException { + DataInputStream dis = new DataInputStream( + new BufferedInputStream(new FileInputStream(new File("data.txt")))); + for (int i = 0; i < numOfInts; i++) + dis.readInt(); + dis.close(); + } + }, + new Tester("Mapped Read") { + @Override + public void test() throws IOException { + FileChannel fc = + new FileInputStream(new File("data.txt")).getChannel(); + IntBuffer ib = fc.map(FileChannel.MapMode.READ_ONLY, + 0 , fc.size()).asIntBuffer(); + while (ib.hasRemaining()) + ib.get(); + fc.close(); + } + }, + new Tester("Stream Read/Write") { + @Override + public void test() throws IOException { + RandomAccessFile raf = new RandomAccessFile( + new File("data.txt"), "rw"); + raf.writeInt(1); + for (int i = 0; i < numOfUbuffInts; i++) { + raf.seek(raf.length() - 4); + raf.writeInt(raf.readInt()); + } + raf.close(); + } + }, + new Tester("Mapped Read/Write") { + @Override + public void test() throws IOException { + FileChannel fc = new RandomAccessFile( + new File("data.txt"),"rw").getChannel(); + IntBuffer ib = fc.map(FileChannel.MapMode.READ_WRITE, + 0,fc.size()).asIntBuffer(); + ib.put(0); + for (int i = 1; i < numOfUbuffInts; i++) + ib.put(ib.get(i-1)); + fc.close(); + } + } + }; + + public static void main(String[] args) { + for (Tester tester : tests) + tester.runTests(); + } +} diff --git a/src/main/java/org/javacore/nio/UsingBuffers.java b/src/main/java/org/javacore/nio/UsingBuffers.java new file mode 100644 index 0000000..bf49962 --- /dev/null +++ b/src/main/java/org/javacore/nio/UsingBuffers.java @@ -0,0 +1,55 @@ +package org.javacore.nio; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; + +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-10-14 15:48:12 + * 利用buffer实现交换相邻字符 + */ +public class UsingBuffers { + + private static void symmetricScaramble(CharBuffer buffer) { + while (buffer.hasRemaining()) { + // 将mark设为position + buffer.mark(); + char c1 = buffer.get(); + char c2 = buffer.get(); + // 重置为以前标记的位置 + buffer.reset(); + buffer.put(c2).put(c1); + } + } + + public static void main(String[] args) { + char[] data = "UsingBuffers".toCharArray(); + // 一个字符两个字节 + ByteBuffer bb = ByteBuffer.allocate(data.length * 2); + CharBuffer cb = bb.asCharBuffer(); + cb.put(data); + // 重绕此缓冲区 + System.out.println(cb.rewind()); + symmetricScaramble(cb); + // 重绕此缓冲区 + System.out.println(cb.rewind()); + symmetricScaramble(cb); + System.out.println(cb.rewind()); + } +} diff --git a/src/main/java/org/javacore/nio/ViewBuffers.java b/src/main/java/org/javacore/nio/ViewBuffers.java new file mode 100644 index 0000000..2e7e0a9 --- /dev/null +++ b/src/main/java/org/javacore/nio/ViewBuffers.java @@ -0,0 +1,77 @@ +package org.javacore.nio; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.DoubleBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.LongBuffer; +import java.nio.ShortBuffer; + +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-10-13 20:40:35 + * 不同视图下的缓冲区 + */ +public class ViewBuffers { + public static void main(String[] args) { + ByteBuffer bb = ByteBuffer.wrap(new byte[]{0,0,0,0,0,0,0,'a'}); + bb.rewind(); + System.out.print("Byte Buffer "); + while (bb.hasRemaining()) + System.out.print(bb.position() + " -> " + bb.get() + ", ");
+ System.out.println();
+
+ CharBuffer cb = ((ByteBuffer)bb.rewind()).asCharBuffer();
+ System.out.print("Char Buffer ");
+ while (cb.hasRemaining())
+ System.out.print(cb.position() + " -> " + cb.get() + ", ");
+ System.out.println();
+
+ ShortBuffer sb = ((ByteBuffer)bb.rewind()).asShortBuffer();
+ System.out.print("Short Buffer ");
+ while (sb.hasRemaining())
+ System.out.print(sb.position() + " -> " + sb.get() + ", ");
+ System.out.println();
+
+ IntBuffer ib = ((ByteBuffer)bb.rewind()).asIntBuffer();
+ System.out.print("Int Buffer ");
+ while (ib.hasRemaining())
+ System.out.print(ib.position() + " -> " + ib.get());
+ System.out.println();
+
+ FloatBuffer fb = ((ByteBuffer)bb.rewind()).asFloatBuffer();
+ System.out.print("Float Buffer ");
+ while (fb.hasRemaining())
+ System.out.print(fb.position() + " -> " + fb.get() + ", ");
+ System.out.println();
+
+ LongBuffer lb = ((ByteBuffer)bb.rewind()).asLongBuffer();
+ System.out.print("Long Buffer ");
+ while (lb.hasRemaining())
+ System.out.print(lb.position() + " -> " + lb.get() + ", ");
+ System.out.println();
+
+ DoubleBuffer db = ((ByteBuffer)bb.rewind()).asDoubleBuffer();
+ System.out.print("Double Buffer ");
+ while (db.hasRemaining())
+ System.out.print(db.position() + " -> " + db.get() + ", ");
+ System.out.println();
+ }
+}
diff --git a/src/main/java/org/javacore/reflection/ArrayCopy.java b/src/main/java/org/javacore/reflection/ArrayCopy.java
new file mode 100644
index 0000000..e68b396
--- /dev/null
+++ b/src/main/java/org/javacore/reflection/ArrayCopy.java
@@ -0,0 +1,51 @@
+package org.javacore.reflection;
+
+import java.lang.reflect.Array;
+import java.util.Arrays;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年11月9日 10:45:19
+ * 反射扩容对象数组
+ */
+public class ArrayCopy {
+ public static void main(String[] args) {
+ int[] a = {1,2,3};
+ a = (int[]) goodCopyOf(a,10);
+ System.out.println(Arrays.toString(a));
+
+ String[] str = {"a","b","c"};
+ str = (String[]) goodCopyOf(str,10);
+ System.out.println(Arrays.toString(str));
+ }
+
+ public static Object goodCopyOf(Object a,int newLength){
+ // 获取Class对象
+ Class cl = a.getClass();
+ // 如果不是数组对象,则返回null;
+ if (!cl.isArray()) return null;
+ // 获取数组组件对象
+ Class componentType = cl.getComponentType();
+ int length = Array.getLength(a);
+ Object newArray = Array.newInstance(componentType,newLength);
+ // 复制数组
+ System.arraycopy(a,0,newArray,0,Math.min(length,newLength));
+ return newArray;
+ }
+}
diff --git a/src/main/java/org/javacore/reflection/EmployeeClass.java b/src/main/java/org/javacore/reflection/EmployeeClass.java
new file mode 100644
index 0000000..558bdde
--- /dev/null
+++ b/src/main/java/org/javacore/reflection/EmployeeClass.java
@@ -0,0 +1,46 @@
+package org.javacore.reflection;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年11月9日 10:45:19
+ * 反射在继承中的案例
+ */
+class Employee {
+ private String name;
+ public Employee(String name){
+ this.name = name;
+ }
+
+ public String getName(){
+ return name;
+ }
+}
+class Manager extends Employee {
+ public Manager(String name) {
+ super(name);
+ }
+}
+public class EmployeeClass {
+ public static void main(String[] args) {
+ Employee employee = new Employee("Jeff");
+ Employee manager = new Manager("Boss");
+ System.out.println(employee.getClass().getName() + " " + employee.getName());
+ System.out.println(manager.getClass().getName() + " " + manager.getName());
+ }
+}
diff --git a/src/main/java/org/javacore/reflection/ObjectAnalyzer.java b/src/main/java/org/javacore/reflection/ObjectAnalyzer.java
new file mode 100644
index 0000000..ee6beca
--- /dev/null
+++ b/src/main/java/org/javacore/reflection/ObjectAnalyzer.java
@@ -0,0 +1,84 @@
+package org.javacore.reflection;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年11月9日 10:45:19
+ * 反射对象分析工具 @{link test/org.javacore.reflection.ObjectAnalyzerTest}
+ */
+public class ObjectAnalyzer {
+ private ArrayList visited = new ArrayList();
+
+ public String toString(Object obj){
+ if (obj == null) return "null";
+ if (visited.contains(obj)) return "...";
+ visited.add(obj);
+
+ // 获取Class对象
+ Class cl = obj.getClass();
+ if (cl == String.class) return (String)obj;
+ // 如果对象是一个数组类
+ if (cl.isArray()){
+ // 获取数组组件
+ String r = cl.getComponentType() + "[]{";
+ for (int i = 0; i < Array.getLength(obj); i++) { + if (i> 0) r += ",";
+ Object val = Array.get(obj,i);
+ // 是否是一个基本类型
+ if (cl.getComponentType().isPrimitive())
+ r += val;
+ else r += toString(val);
+ }
+ return r + "}";
+ }
+
+ String r =cl.getName();
+ do {
+ r += "[";
+ Field[] fields = cl.getDeclaredFields();
+ AccessibleObject.setAccessible(fields,true);
+ for (Field f : fields){
+ if (!Modifier.isStatic(f.getModifiers())){
+ r += f.getName() + "=";
+ try {
+ Class t = f.getType();
+ Object val = f.get(obj);
+ if (t.isPrimitive())
+ r += val;
+ else
+ r +=toString(val);
+ } catch (Exception e){
+ e.printStackTrace();
+ }
+ }
+ }
+ r += "]";
+ cl = cl.getSuperclass();
+ } while (cl != null);
+
+ return r;
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/javacore/reflection/ReflectionTest.java b/src/main/java/org/javacore/reflection/ReflectionTest.java
new file mode 100644
index 0000000..b057cd9
--- /dev/null
+++ b/src/main/java/org/javacore/reflection/ReflectionTest.java
@@ -0,0 +1,127 @@
+package org.javacore.reflection;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年11月9日 10:45:19
+ * 反射对象构造函数、方法及字段
+ */
+public class ReflectionTest {
+ public final int AGE = 1;
+ public static void main(String[] args) {
+ Class cl = null;
+ try {
+ cl = Class.forName("org.javacore.reflection.ReflectionTest");
+ System.out.println("打印析构函数:");
+ printConstructors(cl);
+ System.out.println("打印方法:");
+ printMethods(cl);
+ System.out.println("打印字段:");
+ printFields(cl);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 打印Class对象的析构方法
+ * @param cl
+ */
+ public static void printConstructors(Class cl){
+ // 返回类所有的析构方法
+ Constructor[] constructors = cl.getDeclaredConstructors();
+ for (Constructor c : constructors){
+ // 返回析构方法名称
+ String name = c.getName();
+ System.out.print(" ");
+ // 获取Java语言的修饰符
+ // 修饰符由 Java 虚拟机的 public、protected、private、
+ // final、static、abstract 和 interface 对应的常量组成;
+ String modifiers = Modifier.toString(c.getModifiers());
+ if (modifiers.length()> 0)
+ System.out.print(modifiers + " ");
+ System.out.print(name + "(");
+
+ // 获取析构方法的参数对象列表数组
+ Class[] paramTypes = c.getParameterTypes();
+ for (int i = 0; i < paramTypes.length;i++){ + if (i> 0)
+ System.out.print(", ");
+ System.out.print(paramTypes[i].getName());
+ }
+ System.out.println(");");
+ }
+ }
+
+ /**
+ * 打印对象所有的方法
+ * @param cl
+ */
+ public static void printMethods(Class cl){
+ // 获取类所有方法对象数组
+ Method[] methods = cl.getMethods();
+ for (Method m : methods) {
+ // 获取方法返回对象
+ Class retType = m.getReturnType();
+ String name = m.getName();
+
+ System.out.print(" ");
+ // 获取Java语言的修饰符
+ // 修饰符由 Java 虚拟机的 public、protected、private、
+ // final、static、abstract 和 interface 对应的常量组成;
+ String modifiers = Modifier.toString(cl.getModifiers());
+ if (modifiers.length()> 0)
+ System.out.print(modifiers + " ");
+ System.out.print(retType.getName() +" " + name + "(");
+
+ // 获取方法的参数对象列表数组
+ Class[] paramTypes = m.getParameterTypes();
+ for (int i = 0; i < paramTypes.length;i++){ + if (i> 0)
+ System.out.print(", ");
+ System.out.print(paramTypes[i].getName());
+ }
+ System.out.println(");");
+ }
+ }
+
+ public static void printFields(Class clazz){
+ // 获取字段Field对象数组
+ Field[] fields = clazz.getFields();
+ for (Field field : fields){
+ // 获取字段声明类型对象
+ Class type = field.getType();
+ // 获取字段名称
+ String name = field.getName();
+
+ System.out.print(" ");
+ // 获取Java语言的修饰符
+ // 修饰符由 Java 虚拟机的 public、protected、private、
+ // final、static、abstract 和 interface 对应的常量组成;
+ String modifiers = Modifier.toString(field.getModifiers());
+ if (modifiers.length()> 0)
+ System.out.print(modifiers + " ");
+ System.out.print(type.getName() + " " + name);
+ }
+ }
+}
diff --git a/src/org/javacore/reflection/User.java b/src/main/java/org/javacore/reflection/User.java
similarity index 100%
rename from src/org/javacore/reflection/User.java
rename to src/main/java/org/javacore/reflection/User.java
diff --git a/src/org/javacore/reflection/UserConstructorReflect.java b/src/main/java/org/javacore/reflection/UserConstructorReflect.java
similarity index 100%
rename from src/org/javacore/reflection/UserConstructorReflect.java
rename to src/main/java/org/javacore/reflection/UserConstructorReflect.java
diff --git a/src/main/java/org/javacore/rtti/ClassInitialization.java b/src/main/java/org/javacore/rtti/ClassInitialization.java
new file mode 100644
index 0000000..98a854f
--- /dev/null
+++ b/src/main/java/org/javacore/rtti/ClassInitialization.java
@@ -0,0 +1,67 @@
+package org.javacore.rtti;
+
+import java.util.Random;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年11月2日 16:43:41
+ * Class初始化案例
+ */
+class Initable {
+ static final int staticFinal = 47;
+ static final int staticFinal2 =
+ ClassInitialization.random.nextInt(1000);
+ static {
+ System.out.println("Initializing Initable");
+ }
+}
+
+class Initable2 {
+ static int staticNonFinal = 147;
+ static {
+ System.out.println("Initializing Initable2");
+ }
+}
+
+class Initable3 {
+ static int staticNonFinal = 74;
+ static {
+ System.out.println("Initializing Initable3");
+ }
+}
+
+public class ClassInitialization {
+ public static Random random = new Random(47);
+
+ public static void main(String[] args) throws ClassNotFoundException {
+ // 类中有编译期常量 static Final,则暂时不需要初始化
+ Class initable = Initable.class;
+ System.out.println("After creating Initable ref");
+ System.out.println(Initable.staticFinal);
+ // 调用非编译期常量,强制进行类Initable初始化
+ System.out.println(Initable.staticFinal2);
+
+ // 先进行初始化
+ System.out.println(Initable2.staticNonFinal);
+
+ // 无编译期常量,直接初始化
+ Class initable3 = Class.forName("org.javacore.rtti.Initable3");
+ System.out.println("After creating Initable ref");
+ System.out.println(Initable3.staticNonFinal);
+ }
+}
diff --git a/src/main/java/org/javacore/rtti/ShowMethods.java b/src/main/java/org/javacore/rtti/ShowMethods.java
new file mode 100644
index 0000000..9316df9
--- /dev/null
+++ b/src/main/java/org/javacore/rtti/ShowMethods.java
@@ -0,0 +1,40 @@
+package org.javacore.rtti;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年11月2日 16:43:41
+ * 获取Class方法案例
+ */
+public class ShowMethods {
+ public static void main(String[] args) {
+ try {
+ Class> c = Class.forName("org.javacore.rtti.ShowMethods");
+ Method[] methods = c.getMethods();
+ Constructor[] constructors = c.getConstructors();
+ for (Method m : methods)
+ System.out.println(m.toGenericString());
+ for (Constructor constructor : constructors)
+ System.out.println(constructor.toGenericString());
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/main/java/org/javacore/scheduler/SchedulerExecutorTest.java b/src/main/java/org/javacore/scheduler/SchedulerExecutorTest.java
new file mode 100644
index 0000000..c6c4d0b
--- /dev/null
+++ b/src/main/java/org/javacore/scheduler/SchedulerExecutorTest.java
@@ -0,0 +1,46 @@
+package org.javacore.scheduler; /*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * ScheduledExecutorService的使用
+ * @author BYSocket
+ * @since 2016年01月10日 14:20:00
+ */
+public class SchedulerExecutorTest implements
+ Runnable {
+ private final String jobName;
+
+ public SchedulerExecutorTest(String jobName) {
+ this.jobName = jobName;
+ }
+
+ @Override
+ public void run() {
+ System.out.println("running => " + jobName);
+ }
+
+ public static void main(String[] args) {
+ ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
+ // 一秒
+ executor.scheduleAtFixedRate(new SchedulerExecutorTest("job1"), 1, 1, TimeUnit.SECONDS);
+ // 两秒
+ executor.scheduleWithFixedDelay(new SchedulerExecutorTest("job2"),1,2,TimeUnit.SECONDS);
+ }
+}
diff --git a/src/main/java/org/javacore/scheduler/SchedulerExecutorTest2.java b/src/main/java/org/javacore/scheduler/SchedulerExecutorTest2.java
new file mode 100644
index 0000000..4b413ed
--- /dev/null
+++ b/src/main/java/org/javacore/scheduler/SchedulerExecutorTest2.java
@@ -0,0 +1,116 @@
+package org.javacore.scheduler; /*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * ScheduledExecutorService的使用
+ * @author BYSocket
+ * @since 2016年01月10日 22:02:00
+ */
+public class SchedulerExecutorTest2 implements Runnable{
+
+ private final String jobName;
+
+ public SchedulerExecutorTest2(String jobName) {
+ this.jobName = jobName;
+ }
+
+ @Override
+ public void run() {
+ System.out.println("Date = " + new Date() + ", running => " + jobName);
+ }
+
+ /**
+ * 计算从当前时间currentDate开始,满足条件dayOfWeek, hourOfDay,
+ * minuteOfHour, secondOfMinite的最近时间
+ * @return
+ */
+ public Calendar getEarliestDate(Calendar currentDate, int dayOfWeek,
+ int hourOfDay, int minuteOfHour, int secondOfMinite) {
+ //计算当前时间的WEEK_OF_YEAR,DAY_OF_WEEK, HOUR_OF_DAY, MINUTE,SECOND等各个字段值
+ int currentWeekOfYear = currentDate.get(Calendar.WEEK_OF_YEAR);
+ int currentDayOfWeek = currentDate.get(Calendar.DAY_OF_WEEK);
+ int currentHour = currentDate.get(Calendar.HOUR_OF_DAY);
+ int currentMinute = currentDate.get(Calendar.MINUTE);
+ int currentSecond = currentDate.get(Calendar.SECOND);
+
+ //如果输入条件中的dayOfWeek小于当前日期的dayOfWeek,则WEEK_OF_YEAR需要推迟一周
+ boolean weekLater = false;
+ if (dayOfWeek < currentDayOfWeek) { + weekLater = true; + } else if (dayOfWeek == currentDayOfWeek) { + //当输入条件与当前日期的dayOfWeek相等时,如果输入条件中的 + //hourOfDay小于当前日期的 + //currentHour,则WEEK_OF_YEAR需要推迟一周 + if (hourOfDay < currentHour) { + weekLater = true; + } else if (hourOfDay == currentHour) { + //当输入条件与当前日期的dayOfWeek, hourOfDay相等时, + //如果输入条件中的minuteOfHour小于当前日期的 + //currentMinute,则WEEK_OF_YEAR需要推迟一周 + if (minuteOfHour < currentMinute) { + weekLater = true; + } else if (minuteOfHour == currentSecond) { + //当输入条件与当前日期的dayOfWeek, hourOfDay, + //minuteOfHour相等时,如果输入条件中的 + //secondOfMinite小于当前日期的currentSecond, + //则WEEK_OF_YEAR需要推迟一周 + if (secondOfMinite < currentSecond) { + weekLater = true; + } + } + } + } + if (weekLater) { + //设置当前日期中的WEEK_OF_YEAR为当前周推迟一周 + currentDate.set(Calendar.WEEK_OF_YEAR, currentWeekOfYear + 1); + } + // 设置当前日期中的DAY_OF_WEEK,HOUR_OF_DAY,MINUTE,SECOND为输入条件中的值。 + currentDate.set(Calendar.DAY_OF_WEEK, dayOfWeek); + currentDate.set(Calendar.HOUR_OF_DAY, hourOfDay); + currentDate.set(Calendar.MINUTE, minuteOfHour); + currentDate.set(Calendar.SECOND, secondOfMinite); + return currentDate; + + } + + public static void main(String[] args) { + SchedulerExecutorTest2 executor = new SchedulerExecutorTest2("job1"); + // 获取当前时间 + Calendar currentDate = Calendar.getInstance(); + long currentDateLong = currentDate.getTime().getTime(); + System.out.println("Current Date = " + currentDate.getTime().toString()); + // 计算满足条件的最近一次执行时间 + Calendar earliestDate = executor.getEarliestDate(currentDate,3,16,38,10); + long earliestDateLong = earliestDate.getTime().getTime(); + System.out.println("Earliest Date = " + earliestDate.getTime().toString()); + // 计算从当前时间到最近一次执行时间的时间间隔 + long delay = earliestDateLong - currentDateLong; + // 计算执行周期为一星期 +// long period = 7 * 24 * 60 * 60 * 1000; + long period = 1000; + ScheduledExecutorService service = Executors.newScheduledThreadPool(10); + // 从现在开始delay毫秒之后,每隔一星期执行一次job1 + service.scheduleAtFixedRate(executor, delay, period, + TimeUnit.MILLISECONDS); + } + +} diff --git a/src/main/java/org/javacore/scheduler/TimerTest.java b/src/main/java/org/javacore/scheduler/TimerTest.java new file mode 100644 index 0000000..2253781 --- /dev/null +++ b/src/main/java/org/javacore/scheduler/TimerTest.java @@ -0,0 +1,45 @@ +package org.javacore.scheduler; +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.util.Timer; +import java.util.TimerTask; + +/** + * Timer的使用 + * @author BYSocket + * @since 2016-01-09 22:19:00 + */ +public class TimerTest extends TimerTask{ + + private final String jobName; + + public TimerTest(String jobName) { + this.jobName = jobName; + } + + @Override + public void run() { + System.out.println("run the task => " + jobName);
+ }
+
+ public static void main(String[] args) {
+ // 一种工具,线程用其安排以后在后台线程中执行的任务
+ Timer timer = new Timer();
+ timer.schedule(new TimerTest("Job 1") , 1000 , 1000); // 一秒
+ timer.schedule(new TimerTest("Job 2") , 2000 , 2000); // 两秒
+ }
+}
diff --git a/src/main/java/org/javacore/stream/CollectStreamTest.java b/src/main/java/org/javacore/stream/CollectStreamTest.java
new file mode 100644
index 0000000..dcff4ae
--- /dev/null
+++ b/src/main/java/org/javacore/stream/CollectStreamTest.java
@@ -0,0 +1,33 @@
+package org.javacore.stream;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ *
+ * Created by bysocket on 16/7/14.
+ */
+public class CollectStreamTest {
+ public static void main(String[] args) {
+ List list = Arrays.asList(1,2,3,4);
+ Double result = list.stream().collect(Collectors.averagingDouble(d->d*2));
+ System.out.println(result);
+ }
+}
diff --git a/src/main/java/org/javacore/stream/CollectionStreamTest.java b/src/main/java/org/javacore/stream/CollectionStreamTest.java
new file mode 100644
index 0000000..7d842a1
--- /dev/null
+++ b/src/main/java/org/javacore/stream/CollectionStreamTest.java
@@ -0,0 +1,79 @@
+package org.javacore.stream;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * Stream API 集合的流式操作
+ *
+ * Created by bysocket on 16/7/13.
+ */
+public class CollectionStreamTest {
+ public static void main(String[] args) {
+ List list = new ArrayList();
+ list.add("aa");
+ list.add("cccc");
+ list.add("bbb");
+
+ /**
+ * Stream的使用:
+ * 创建/获取流 -> 中间操作(过滤、转换等) -> 终止操作( 聚合、收集结果)
+ */
+ list.stream().forEach(System.out::println);
+ System.out.println();
+
+ /**
+ * 过滤
+ * collect语法 {@link StreamCollectTest}
+ */
+ List list0 = list.stream().filter(str -> str.startsWith("cc")).collect(Collectors.toList());
+ List list1 = list.stream().filter(str -> str.startsWith("aa")).collect(Collectors.toList());
+
+ list0.stream().forEach(System.out::println);
+ list1.stream().forEach(System.out::println);
+ System.out.println();
+
+ /**
+ * 转换
+ */
+ List list2 = list.stream().map(str -> str.replace("c","*")).collect(Collectors.toList());
+
+ list2.stream().forEach(System.out::println);
+ System.out.println();
+
+ /**
+ * 提取
+ * 从skip开始至limit位置为止
+ */
+ List list3 = list.stream().skip(0).limit(1).collect(Collectors.toList());
+
+ list3.stream().forEach(System.out::println);
+ System.out.println();
+
+ /**
+ * 组合
+ */
+ List list4 = Stream.concat(list.stream(),list.stream()).collect(Collectors.toList());
+
+ list4.stream().forEach(System.out::println);
+ System.out.println();
+ }
+}
diff --git a/src/main/java/org/javacore/stream/CollectionStreamTest01.java b/src/main/java/org/javacore/stream/CollectionStreamTest01.java
new file mode 100644
index 0000000..42a8499
--- /dev/null
+++ b/src/main/java/org/javacore/stream/CollectionStreamTest01.java
@@ -0,0 +1,38 @@
+package org.javacore.stream;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Stream API 集合的流式操作
+ *
+ * Created by bysocket on 16/7/13.
+ */
+public class CollectionStreamTest01 {
+ public static void main(String[] args) {
+ List strList = Arrays.asList("a1", "a2", "c3", "c6", "c4");
+
+ strList
+ .stream()
+ .filter(str -> str.startsWith("c"))
+ .map(String::toUpperCase)
+ .sorted()
+ .forEach(System.out::println);
+ }
+}
diff --git a/src/main/java/org/javacore/stream/ConcatStreamTest.java b/src/main/java/org/javacore/stream/ConcatStreamTest.java
new file mode 100644
index 0000000..4ce98c1
--- /dev/null
+++ b/src/main/java/org/javacore/stream/ConcatStreamTest.java
@@ -0,0 +1,38 @@
+package org.javacore.stream;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * 组合 - 流
+ *
+ * Created by bysocket on 16/7/14.
+ */
+public class ConcatStreamTest {
+ public static void main(String[] args) {
+ List list1 = Arrays.asList("a","b","c");
+ List list2 = Arrays.asList("d","e","f");
+
+ // 组合list1和list2的流
+ List result = Stream.concat(list1.stream(),list2.stream()).collect(Collectors.toList());
+ result.stream().forEach(System.out::println);
+ }
+}
diff --git a/src/main/java/org/javacore/stream/CountFilterStreamTest.java b/src/main/java/org/javacore/stream/CountFilterStreamTest.java
new file mode 100644
index 0000000..8938156
--- /dev/null
+++ b/src/main/java/org/javacore/stream/CountFilterStreamTest.java
@@ -0,0 +1,43 @@
+package org.javacore.stream;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 过滤
+ * 流的元素数量
+ *
+ * Created by bysocket on 16/7/14.
+ */
+public class CountFilterStreamTest {
+ public static void main(String[] args) {
+ List list1 = Arrays.asList("a","b","ac");
+
+ // filter 过滤
+ List result = list1.stream().filter(str -> str.startsWith("a")).collect(Collectors.toList());
+ result.stream().forEach(System.out::println);
+ System.out.println();
+
+ // count 流的元素数量
+ long l = list1.stream().filter(str -> str.startsWith("a")).count();
+ System.out.println("list1 字符从a开始的数量:" + l);
+
+ }
+}
diff --git a/src/main/java/org/javacore/stream/CreateStreamTest.java b/src/main/java/org/javacore/stream/CreateStreamTest.java
new file mode 100644
index 0000000..5ee3111
--- /dev/null
+++ b/src/main/java/org/javacore/stream/CreateStreamTest.java
@@ -0,0 +1,27 @@
+package org.javacore.stream;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * 创建流
+ *
+ * Created by bysocket on 16/7/18.
+ */
+public class CreateStreamTest {
+ public static void main(String[] args) {
+ }
+}
diff --git a/src/main/java/org/javacore/stream/DistinctStreamTest.java b/src/main/java/org/javacore/stream/DistinctStreamTest.java
new file mode 100644
index 0000000..639167e
--- /dev/null
+++ b/src/main/java/org/javacore/stream/DistinctStreamTest.java
@@ -0,0 +1,36 @@
+package org.javacore.stream;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 去重
+ *
+ * Created by bysocket on 16/7/14.
+ */
+public class DistinctStreamTest {
+ public static void main(String[] args) {
+ List list1 = Arrays.asList("a","b","b","b","ac");
+
+ // 去重
+ List result = list1.stream().distinct().collect(Collectors.toList());
+ result.stream().forEach(str -> System.out.print(str + " -> "));
+ }
+}
diff --git a/src/main/java/org/javacore/stream/SortedStreamTest.java b/src/main/java/org/javacore/stream/SortedStreamTest.java
new file mode 100644
index 0000000..1ffed70
--- /dev/null
+++ b/src/main/java/org/javacore/stream/SortedStreamTest.java
@@ -0,0 +1,33 @@
+package org.javacore.stream;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 排序
+ *
+ * Created by bysocket on 16/7/14.
+ */
+public class SortedStreamTest {
+ public static void main(String[] args) {
+ List list1 = Arrays.asList("a","e","b","ac");
+ // 排序
+ list1.stream().sorted().forEach(str -> System.out.print(str + " -> "));
+ }
+}
diff --git a/src/main/java/org/javacore/thread/BasicThreads.java b/src/main/java/org/javacore/thread/BasicThreads.java
new file mode 100644
index 0000000..f2aa6bb
--- /dev/null
+++ b/src/main/java/org/javacore/thread/BasicThreads.java
@@ -0,0 +1,32 @@
+package org.javacore.thread;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年11月2日 17:06:48
+ * 线程简单使用-启动LiftOff线程{@link LiftOff}
+ */
+public class BasicThreads {
+ public static void main(String[] args) {
+ // 创建新的线程
+ Thread t = new Thread(new LiftOff());
+ // 执行线程
+ t.start();
+ System.out.println("Waiting for LiftOff");
+ }
+}
diff --git a/src/main/java/org/javacore/thread/CachedThreadPool.java b/src/main/java/org/javacore/thread/CachedThreadPool.java
new file mode 100644
index 0000000..949cb37
--- /dev/null
+++ b/src/main/java/org/javacore/thread/CachedThreadPool.java
@@ -0,0 +1,36 @@
+package org.javacore.thread;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年11月2日 17:21:04
+ * 线程池CachedThreadPool的简单使用-启动LiftOff线程{@link LiftOff}
+ */
+public class CachedThreadPool {
+ public static void main(String[] args) {
+ // 创建新线程的线程池
+ ExecutorService exec = Executors.newCachedThreadPool();
+ for (int i = 0 ; i < 5; i++) + exec.execute(new LiftOff()); // 由线程池Ececutor决定执行给定的线程。 + // 顺序关闭,执行以前提交的线程,不接受新的线程。 + exec.shutdown(); + } +} diff --git a/src/main/java/org/javacore/thread/CallableDemo.java b/src/main/java/org/javacore/thread/CallableDemo.java new file mode 100644 index 0000000..8d57eee --- /dev/null +++ b/src/main/java/org/javacore/thread/CallableDemo.java @@ -0,0 +1,71 @@ +package org.javacore.thread; + +import java.util.ArrayList; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +/** + * Created by BYSocket on 2015/11/2. + * + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-11-2 18:58:36 + * Callable接口的使用 --- 实现带返回值的任务 + */ + +// Callable实现类task,指定其类型参数 +class TaskWithResult implements Callable {
+
+ private int id;
+ public TaskWithResult(int id) {
+ this.id = id;
+ }
+
+ @Override
+ public String call() throws Exception {
+ return "result of TaskWithResult " + id;
+ }
+}
+
+public class CallableDemo {
+ public static void main(String[] args) {
+ // 创建一个新的线程池
+ ExecutorService exec = Executors.newCachedThreadPool();
+ // Callable实现类task的返回结果集
+ ArrayList> results = new ArrayList();
+ for (int i = 0; i < 5 ; i++) + results.add(exec.submit(new TaskWithResult(i)));// 使用submit来启动Tasks + + // 异步计算的结果 + for (Future fs : results)
+ try {
+ // get阻塞,直至获取结果
+ System.out.println(fs.get());
+ } catch (InterruptedException e) {
+ System.out.println(e);
+ e.printStackTrace();
+ } catch (ExecutionException e) {
+ System.out.println(e);
+ e.printStackTrace();
+ } finally {
+ exec.shutdown();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/javacore/thread/DaemonFromFactory.java b/src/main/java/org/javacore/thread/DaemonFromFactory.java
new file mode 100644
index 0000000..702eaea
--- /dev/null
+++ b/src/main/java/org/javacore/thread/DaemonFromFactory.java
@@ -0,0 +1,55 @@
+package org.javacore.thread;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by BYSocket on 2015年11月2日.
+ *
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年11月3日 18:17:58
+ * 后台线程工厂类的使用
+ */
+public class DaemonFromFactory implements Runnable {
+ @Override
+ public void run() {
+ try {
+ while (true){
+ TimeUnit.MICROSECONDS.sleep(100);
+ System.out.println(Thread.currentThread() + " " + this);
+ }
+ } catch (InterruptedException e) {
+ System.out.println("sleep() interrupted");
+ }
+ }
+
+ public static void main(String[] args) throws InterruptedException {
+ // 使用提供的线程工厂类,创建线程池
+ ExecutorService exec =
+ Executors.newCachedThreadPool(new DaemonThreadFactory());
+ for (int i = 0 ; i < 10 ; i++) + exec.execute(new DaemonFromFactory());// 此Runnable实现类,经过线程工厂创建 + // 关闭线程池 + exec.shutdown(); + System.out.println("任务已经全部启动"); + TimeUnit.MICROSECONDS.sleep(500); + } + +} diff --git a/src/main/java/org/javacore/thread/DaemonThreadFactory.java b/src/main/java/org/javacore/thread/DaemonThreadFactory.java new file mode 100644 index 0000000..9183815 --- /dev/null +++ b/src/main/java/org/javacore/thread/DaemonThreadFactory.java @@ -0,0 +1,36 @@ +package org.javacore.thread; + +import java.util.concurrent.ThreadFactory; + +/** + * Created by BYSocket on 2015/11/2. + * + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-11-3 18:17:49 + * 线程工厂类 - 将线程设置为后台线程 + */ +public class DaemonThreadFactory implements ThreadFactory { + + @Override + public Thread newThread(Runnable r) { + Thread t = new Thread(r); + t.setDaemon(true); + return t; + } +} diff --git a/src/main/java/org/javacore/thread/DaemonsDontRunFinally.java b/src/main/java/org/javacore/thread/DaemonsDontRunFinally.java new file mode 100644 index 0000000..6794ee6 --- /dev/null +++ b/src/main/java/org/javacore/thread/DaemonsDontRunFinally.java @@ -0,0 +1,50 @@ +package org.javacore.thread; + +import java.util.concurrent.TimeUnit; + +/** + * Created by BYSocket on 2015/11/2. + * + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-11-3 18:17:58 + * 后台线程遇到Finally + */ +class ADaemon implements Runnable { + + @Override + public void run() { + try { + System.out.println("启动ADaemon"); + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e ){ + System.out.println("InterruptedException"); + } finally { + // 因为main是非后台线程,main线程结束。ADaemon后台线程也就结束。因此可能没到finally就结束了。 + System.out.println("finally 运行吗?"); + } + } +} +public class DaemonsDontRunFinally { + public static void main(String[] args) { + Thread t = new Thread(new ADaemon()); + // 设置线程为后台线程 + t.setDaemon(true); + t.start(); + } +} diff --git a/src/main/java/org/javacore/thread/FixedThreadPool.java b/src/main/java/org/javacore/thread/FixedThreadPool.java new file mode 100644 index 0000000..99e80a9 --- /dev/null +++ b/src/main/java/org/javacore/thread/FixedThreadPool.java @@ -0,0 +1,36 @@ +package org.javacore.thread; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-11-2 17:06:48 + * 线程池FixedThreadPool的简单使用-启动LiftOff线程{@link LiftOff} + */ +public class FixedThreadPool { + public static void main(String[] args) { + // 创建固定线程为5的线程池 + ExecutorService exec = Executors.newFixedThreadPool(5); + for (int i = 0; i < 5 ;i++) + exec.execute(new LiftOff());// 由线程池Ececutor决定执行给定的线程。 + // 顺序关闭,执行以前提交的线程,不接受新的线程。 + exec.shutdown(); + } +} diff --git a/src/main/java/org/javacore/thread/LiftOff.java b/src/main/java/org/javacore/thread/LiftOff.java new file mode 100644 index 0000000..7f36af6 --- /dev/null +++ b/src/main/java/org/javacore/thread/LiftOff.java @@ -0,0 +1,47 @@ +package org.javacore.thread; + +/* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-11-2 16:56:43 + * Runnable接口的实现类LiftOff + */ +public class LiftOff implements Runnable{ + + protected int countDown = 10; + private static int taskCount = 0; + private final int id = taskCount++; + + public LiftOff(){} + public LiftOff(int countDown){ + this.countDown = countDown; + } + + public String status(){ + return "#" + id + "(" + + (countDown>0 ? countDown : "LiftOff!") + "), ";
+ }
+ @Override
+ public void run() {
+ while (countDown--> 0){
+ System.out.println(status());
+ // 暂停当前正在执行线程,并执行其他线程。
+ Thread.yield();
+ }
+ }
+}
diff --git a/src/main/java/org/javacore/thread/MoreBasicThreads.java b/src/main/java/org/javacore/thread/MoreBasicThreads.java
new file mode 100644
index 0000000..4b31be3
--- /dev/null
+++ b/src/main/java/org/javacore/thread/MoreBasicThreads.java
@@ -0,0 +1,30 @@
+package org.javacore.thread;
+
+/*
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年11月2日 17:09:33
+ * 线程简单使用-启动多个LiftOff线程{@link LiftOff}
+ */
+public class MoreBasicThreads {
+ public static void main(String[] args) {
+ for (int i = 0; i < 5 ; i++) + new Thread(new LiftOff()).start(); + System.out.println("Waiting for LiftOff"); + } +} diff --git a/src/org/javacore/thread/MyRunnable.java b/src/main/java/org/javacore/thread/MyRunnable.java similarity index 100% rename from src/org/javacore/thread/MyRunnable.java rename to src/main/java/org/javacore/thread/MyRunnable.java diff --git a/src/org/javacore/thread/MyThread.java b/src/main/java/org/javacore/thread/MyThread.java similarity index 100% rename from src/org/javacore/thread/MyThread.java rename to src/main/java/org/javacore/thread/MyThread.java diff --git a/src/main/java/org/javacore/thread/ProcessBuilderTest.java b/src/main/java/org/javacore/thread/ProcessBuilderTest.java new file mode 100644 index 0000000..244da77 --- /dev/null +++ b/src/main/java/org/javacore/thread/ProcessBuilderTest.java @@ -0,0 +1,36 @@ +package org.javacore.thread; /* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.IOException; +import java.util.Scanner; + +/** + * Java进程调用CMD + * VM options => -Dfile.encoding="GBK"
+ * @author BYSocket
+ * @since 2016年01月18日 16:08:00
+ */
+public class ProcessBuilderTest {
+ public static void main(String[] args) throws IOException {
+ ProcessBuilder pb = new ProcessBuilder("cmd","/c","ipconfig/all");
+ Process p = pb.start();
+
+ Scanner scanner = new Scanner(p.getInputStream());
+ while (scanner.hasNext())
+ System.out.println(scanner.next());
+ scanner.close();
+ }
+}
diff --git a/src/main/java/org/javacore/thread/SimpleDaemons.java b/src/main/java/org/javacore/thread/SimpleDaemons.java
new file mode 100644
index 0000000..253e93b
--- /dev/null
+++ b/src/main/java/org/javacore/thread/SimpleDaemons.java
@@ -0,0 +1,53 @@
+package org.javacore.thread;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by BYSocket on 2015年11月2日.
+ *
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Jeff Lee
+ * @since 2015年11月3日 18:09:06
+ * Daemon后台线程的简单使用
+ */
+public class SimpleDaemons implements Runnable{
+ @Override
+ public void run() {
+ try {
+ while (true){
+ TimeUnit.MICROSECONDS.sleep(1000);
+ System.out.println(Thread.currentThread() + " " + this);
+ }
+ } catch (InterruptedException e) {
+ System.out.println("sleep() interrupted");
+ }
+ }
+
+ // main是非后台线程
+ public static void main(String[] args) throws InterruptedException {
+ for (int i = 0 ; i < 10 ; i++){ + // 创建一个新线程 + Thread daemon = new Thread(new SimpleDaemons()); + // 设置为后台线程 + daemon.setDaemon(true); + daemon.start(); + } + System.out.println("所有任务已启动"); + // 如果main结束,那么同时会杀死所有后台线程,多次运行你会发现,可能打印的后台线程数不定 + TimeUnit.MICROSECONDS.sleep(175); + } +} diff --git a/src/main/java/org/javacore/thread/SimplePriorities.java b/src/main/java/org/javacore/thread/SimplePriorities.java new file mode 100644 index 0000000..340a27b --- /dev/null +++ b/src/main/java/org/javacore/thread/SimplePriorities.java @@ -0,0 +1,68 @@ +package org.javacore.thread; + +/** + * Created by BYSocket on 2015/11/2. + * + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * @author Jeff Lee + * @since 2015-11-3 09:05:03 + * 线程优先级的使用 + */ +public class SimplePriorities implements Runnable { + private int countDown = 5; + private volatile double d; + private int priority; + + public SimplePriorities(int priority){ + this.priority = priority; + } + + public String toString(){ + // 获取当前执行的线程对象的引用 + return Thread.currentThread() + ": " + countDown; + } + + @Override + public void run() { + // 获取当前执行的线程对象的引用,并设置其优先级。 + Thread.currentThread().setPriority(priority); + + while (true){ + for (int i = 1; i < 100000; i++){ + d += (Math.PI + Math.E) / (double) i; + if (i % 1000 == 0) + Thread.yield(); + } + System.out.println(this); + if (--countDown == 0) return; + } + } + + public static void main(String[] args) { + // 创建新的线程池 + ExecutorService exec = Executors.newCachedThreadPool(); + for (int i = 0; i < 5 ;i++) + exec.execute(new SimplePriorities(Thread.MIN_PRIORITY));// 由线程池决定执行线程,并设置优先级最低 + exec.execute(new SimplePriorities(Thread.MAX_PRIORITY));// 由线程池决定执行线程,并设置优先级最高 + // 顺序关闭,执行以前提交的线程,不接受新的线程 + exec.shutdown(); + } +} diff --git a/src/main/java/org/javacore/thread/SingleThreadExecutor.java b/src/main/java/org/javacore/thread/SingleThreadExecutor.java new file mode 100644 index 0000000..ce69b67 --- /dev/null +++ b/src/main/java/org/javacore/thread/SingleThreadExecutor.java @@ -0,0 +1,38 @@ +package org.javacore.thread; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * Created by BYSocket on 2015/11/2. + * + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Jeff Lee + * @since 2015-11-2 18:58:36 + * SingleThreadExecutor的使用-启动LiftOff线程{@link LiftOff} + */ +public class SingleThreadExecutor { + public static void main(String[] args) { + // 创建使用单个worker线程的线程池Executor + ExecutorService exec = Executors.newSingleThreadExecutor(); + for (int i = 0; i < 5; i++) + exec.execute(new LiftOff());// 由Executor决定执行给定的线程 + // 顺序关闭,执行已提交的线程,不准添加新的线程 + exec.shutdown(); + } +} diff --git a/src/main/java/org/javacore/thread/SleepRunThread.java b/src/main/java/org/javacore/thread/SleepRunThread.java new file mode 100644 index 0000000..8ee298b --- /dev/null +++ b/src/main/java/org/javacore/thread/SleepRunThread.java @@ -0,0 +1,43 @@ +package org.javacore.thread; /* + * Copyright [2015] [Jeff Lee] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Thread中start和run的区别 + * @author BYSocket + * @since 2016-01-18 15:55:00 + */ +public class SleepRunThread { + public static void main(String[] args) { + System.out.println("当前线程ID => " + Thread.currentThread().getId());
+
+ SRThread t1 = new SRThread("t1");
+ t1.start();
+ SRThread t2 = new SRThread("t2");
+ t2.run();
+ }
+}
+class SRThread extends Thread {
+ private String name;
+
+ public SRThread(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public void run() {
+ System.out.println("name:" + name +", 线程ID => " + Thread.currentThread().getId());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/javacore/thread/SleepingTask.java b/src/main/java/org/javacore/thread/SleepingTask.java
new file mode 100644
index 0000000..6d989f4
--- /dev/null
+++ b/src/main/java/org/javacore/thread/SleepingTask.java
@@ -0,0 +1,52 @@
+package org.javacore.thread;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by BYSocket on 2015年11月2日.
+ *
+ * Copyright [2015] [Jeff Lee]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Jeff Lee
+ * @since 2015年11月3日 09:04:16
+ * 休眠线程sleep的使用
+ */
+public class SleepingTask extends LiftOff {
+ @Override
+ public void run(){
+ while(countDown--> 0){
+ try {
+ System.out.println(status());
+ // 老版本调用:Thread.sleep(1000);
+ TimeUnit.MICROSECONDS.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static void main(String[] args) {
+ // 创建新的线程池
+ ExecutorService exec = Executors.newCachedThreadPool();
+ for (int i = 0; i < 5;i++) + exec.execute(new SleepingTask());// 由线程池决定执行线程 + // 顺序关闭,执行以前提交的线程,不接受新的线程 + exec.shutdown(); + } +} diff --git a/src/main/java/org/javacore/thread/ThreadInfo.java b/src/main/java/org/javacore/thread/ThreadInfo.java new file mode 100644 index 0000000..04edc13 --- /dev/null +++ b/src/main/java/org/javacore/thread/ThreadInfo.java @@ -0,0 +1,83 @@ +package org.javacore.thread; + + +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; + +/** + * 描述:线程优先级案例 + * Created by bysocket on 16/2/24. + */ +public class ThreadInfo { + public static void main(String[] args) { + Thread threads[] = new Thread[10]; + Thread.State status[] = new Thread.State[10]; + for (int i = 0; i < 10; i++) { + threads[i] = new Thread(new Calculator(i)); + if ((i % 2) == 0) { + threads[i].setPriority(Thread.MAX_PRIORITY); + } else { + threads[i].setPriority(Thread.MIN_PRIORITY); + } +// threads[i].setName(""); + } + + try { + // 将线程的信息写入log文件 + FileWriter fw = new FileWriter(".\\log.txt"); + PrintWriter pw = new PrintWriter(fw); + + for (int i = 0; i <10 ;i++) { + pw.println("Main: Status of Thread " + i + " : " + + threads[i].getState()); + status[i] = threads[i].getState(); + } + + // 启动线程 + for (int i = 0; i < 10 ;i++) + threads[i].start(); + + boolean finish = false; + while (!finish) { + for(int i = 0;i < 10 ;i++) { + if (threads[i].getState() != status[i]) { + writeThreadInfo(pw,threads[i],status[i]); + status[i] = threads[i].getState(); + } + } + finish = true; + for (int i = 0;i < 10 ;i++) { + finish = finish && (threads[i].getState() == Thread.State.TERMINATED);//中断 + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + private static void writeThreadInfo(PrintWriter pw, Thread thread, Thread.State status) { + pw.printf("Main: Id %d - $s\n",thread.getId(),thread.getName()); + pw.printf("Main: Priority: %d\n",thread.getPriority()); + pw.printf("Main: OldState: %s\n",status); + pw.printf("Main: New State: %s\n",thread.getState()); + pw.printf("*****************************************\n"); + } +} +class Calculator implements Runnable { + + private int number; + + public Calculator(int number) { + this.number = number; + } + + @Override + public void run() { + for (int i = 0;i <=10; i++) { + System.out.printf("%s: %d * %d = %d\n", + Thread.currentThread().getName(), + number, i, i * number); + } + } +} diff --git a/src/main/java/org/javacore/thread/ThreadInterrupt.java b/src/main/java/org/javacore/thread/ThreadInterrupt.java new file mode 100644 index 0000000..3d7009d --- /dev/null +++ b/src/main/java/org/javacore/thread/ThreadInterrupt.java @@ -0,0 +1,22 @@ +package org.javacore.thread; + +/** + * Created by bysocket on 16/2/24. + */ +public class ThreadInterrupt { + public static void main(String[] args) throws InterruptedException { + Thread inThread = new Thread(new InterrupThread()); + inThread.start(); + Thread.sleep(1000); + inThread.interrupt(); + } +} +class InterrupThread implements Runnable { + + private int num = 1; + @Override + public void run() { + while (true) + System.out.println("true ----> " + num++);
+ }
+}
diff --git a/src/main/java/org/javacore/thread/daemon/CleanerTask.java b/src/main/java/org/javacore/thread/daemon/CleanerTask.java
new file mode 100644
index 0000000..eba932c
--- /dev/null
+++ b/src/main/java/org/javacore/thread/daemon/CleanerTask.java
@@ -0,0 +1,52 @@
+package org.javacore.thread.daemon;
+
+import java.util.Date;
+import java.util.Deque;
+
+/**
+ * 描述:管理这个队列,如果事件超过10秒钟,就会被移除
+ * Created by bysocket on 16/3/4.
+ */
+public class CleanerTask extends Thread{
+ private Deque deque;
+
+ public CleanerTask(Deque deque) {
+ this.deque = deque;
+ setDaemon(true);
+ }
+
+ @Override
+ public void run() {
+ while (true) {
+ Date date = new Date();
+ clean(date);
+ }
+ }
+
+ /**
+ * 删除该时间前10s内创建的事件对象
+ * @param date
+ */
+ private void clean(Date date) {
+ long difference = 0;
+ boolean delete;
+ if (deque.size() == 0) {
+ return;
+ }
+ delete = false;
+
+ do {
+ Event e = deque.getLast();
+ difference = date.getTime() - e.getDate().getTime();
+ if (difference> 10000) {
+ System.out.printf("Cleaner: %s \n",e.getEvent());
+ deque.removeLast();
+ delete = true;
+ }
+ } while (difference> 10000);
+
+ if (delete) {
+ System.out.printf("Cleaner: Size of the queue: %d\n",deque.size());
+ }
+ }
+}
diff --git a/src/main/java/org/javacore/thread/daemon/DaemonTest.java b/src/main/java/org/javacore/thread/daemon/DaemonTest.java
new file mode 100644
index 0000000..3758870
--- /dev/null
+++ b/src/main/java/org/javacore/thread/daemon/DaemonTest.java
@@ -0,0 +1,23 @@
+package org.javacore.thread.daemon;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+
+/**
+ * 1. 知道3个WriteTask线程休眠后,CleanerTask才执行
+ * 2. 从结果中,可以看出队列维持在一定数量当中
+ * Created by bysocket on 16/3/4.
+ */
+public class DaemonTest {
+ public static void main(String[] args) {
+ Deque deque = new ArrayDeque();
+ WriterTask writerTask = new WriterTask(deque);
+ for (int i = 0; i < 3 ; i++) { + Thread thread = new Thread(writerTask); + thread.start(); + } + + CleanerTask cleanerTask = new CleanerTask(deque); + cleanerTask.start(); + } +} diff --git a/src/main/java/org/javacore/thread/daemon/Event.java b/src/main/java/org/javacore/thread/daemon/Event.java new file mode 100644 index 0000000..3030ccb --- /dev/null +++ b/src/main/java/org/javacore/thread/daemon/Event.java @@ -0,0 +1,28 @@ +package org.javacore.thread.daemon; + +import java.util.Date; + +/** + * 描述:事件类 + * Created by bysocket on 16/3/4. + */ +public class Event { + private Date date; + private String event; + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + public String getEvent() { + return event; + } + + public void setEvent(String event) { + this.event = event; + } +} diff --git a/src/main/java/org/javacore/thread/daemon/WriterTask.java b/src/main/java/org/javacore/thread/daemon/WriterTask.java new file mode 100644 index 0000000..70e3e5f --- /dev/null +++ b/src/main/java/org/javacore/thread/daemon/WriterTask.java @@ -0,0 +1,33 @@ +package org.javacore.thread.daemon; + +import java.util.Date; +import java.util.Deque; +import java.util.concurrent.TimeUnit; + +/** + * 描述:写事件到一个队列 + * Created by bysocket on 16/3/4. + */ +public class WriterTask implements Runnable { + private Deque deque;
+
+ public WriterTask(Deque deque) {
+ this.deque = deque;
+ }
+
+ @Override
+ public void run() {
+ for (int i = 1; i < 100; i++) { + Event event = new Event(); + event.setDate(new Date()); + event.setEvent(String.format("The thread %s has generated an event",Thread.currentThread().getId())); + deque.addFirst(event); + + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } +} diff --git a/src/main/java/org/javacore/thread/join/DSLoader.java b/src/main/java/org/javacore/thread/join/DSLoader.java new file mode 100644 index 0000000..07e8019 --- /dev/null +++ b/src/main/java/org/javacore/thread/join/DSLoader.java @@ -0,0 +1,19 @@ +package org.javacore.thread.join; + +import java.util.concurrent.TimeUnit; + +/** + * Created by bysocket on 16/3/3. + */ +public class DSLoader implements Runnable { + @Override + public void run() { + System.out.println("begining the DSLoader"); + try { + TimeUnit.SECONDS.sleep(4); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("DSLoader has finished"); + } +} diff --git a/src/main/java/org/javacore/thread/join/JoinTest.java b/src/main/java/org/javacore/thread/join/JoinTest.java new file mode 100644 index 0000000..d0ed248 --- /dev/null +++ b/src/main/java/org/javacore/thread/join/JoinTest.java @@ -0,0 +1,20 @@ +package org.javacore.thread.join; + +/** + * Created by bysocket on 16/3/3. + */ +public class JoinTest { + public static void main(String[] args) throws InterruptedException { + Thread t1 = new Thread(new DSLoader()); + Thread t2 = new Thread(new NetLoader()); + + t1.start(); + t2.start(); + + //可以注释其中一个加深理解 + t1.join(); + //t2.join(); + + System.out.println("ending all"); + } +} diff --git a/src/main/java/org/javacore/thread/join/NetLoader.java b/src/main/java/org/javacore/thread/join/NetLoader.java new file mode 100644 index 0000000..951b214 --- /dev/null +++ b/src/main/java/org/javacore/thread/join/NetLoader.java @@ -0,0 +1,19 @@ +package org.javacore.thread.join; + +import java.util.concurrent.TimeUnit; + +/** + * Created by bysocket on 16/3/3. + */ +public class NetLoader implements Runnable { + @Override + public void run() { + System.out.println("begining the NetLoader"); + try { + TimeUnit.SECONDS.sleep(6); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println("NetLoader has finished"); + } +} diff --git a/src/main/java/org/javacore/thread/threadlocal/SafeTask.java b/src/main/java/org/javacore/thread/threadlocal/SafeTask.java new file mode 100644 index 0000000..3037ad8 --- /dev/null +++ b/src/main/java/org/javacore/thread/threadlocal/SafeTask.java @@ -0,0 +1,36 @@ +package org.javacore.thread.threadlocal; + +import java.util.Date; +import java.util.concurrent.TimeUnit; + +/** + * 描述:看类里面说明 + * Created by bysocket on 16/3/8. + */ +public class SafeTask implements Runnable{ + /** + * ThreadLocal对象不会被所有线程共享 + * --> 线程局部变量 <-- + */ + private static ThreadLocal startDate = new ThreadLocal(){
+ /**
+ * 隐式实现初始化对象
+ * @return
+ */
+ @Override
+ protected Date initialValue() {
+ return new Date();
+ }
+ };
+
+ @Override
+ public void run() {
+ System.out.printf("Starting Thread:%s : %s\n",Thread.currentThread().getId(),startDate.get());
+ try {
+ TimeUnit.SECONDS.sleep((int) Math.rint(Math.random() * 10));
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ System.out.printf("Finish Thread:%s : %s\n",Thread.currentThread().getId(),startDate.get());
+ }
+}
diff --git a/src/main/java/org/javacore/thread/threadlocal/SafeTest.java b/src/main/java/org/javacore/thread/threadlocal/SafeTest.java
new file mode 100644
index 0000000..0202b0e
--- /dev/null
+++ b/src/main/java/org/javacore/thread/threadlocal/SafeTest.java
@@ -0,0 +1,23 @@
+package org.javacore.thread.threadlocal;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 描述:可以看到线程每个有不同的启动时间,但是结束时间也会不相同.
+ * Created by bysocket on 16/3/8.
+ */
+public class SafeTest {
+ public static void main(String[] args) {
+ SafeTask task = new SafeTask();
+ for (int i = 0 ; i < 10; i++) { + Thread thread = new Thread(task); + thread.start(); + + try { + TimeUnit.SECONDS.sleep(2); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } +} diff --git a/src/main/java/org/javacore/thread/threadlocal/UnsafeTask.java b/src/main/java/org/javacore/thread/threadlocal/UnsafeTask.java new file mode 100644 index 0000000..2aed77d --- /dev/null +++ b/src/main/java/org/javacore/thread/threadlocal/UnsafeTask.java @@ -0,0 +1,24 @@ +package org.javacore.thread.threadlocal; + +import java.util.Date; +import java.util.concurrent.TimeUnit; + +/** + * 描述:私有变量会被所有线程共享 + * Created by bysocket on 16/3/8. + */ +public class UnsafeTask implements Runnable{ + private Date startDate; + + @Override + public void run() { + startDate = new Date(); + System.out.printf("Starting Thread:%s : %s\n",Thread.currentThread().getId(),startDate); + try { + TimeUnit.SECONDS.sleep((int) Math.rint(Math.random() * 10)); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.printf("Finish Thread:%s : %s\n",Thread.currentThread().getId(),startDate); + } +} diff --git a/src/main/java/org/javacore/thread/threadlocal/UnsafeTest.java b/src/main/java/org/javacore/thread/threadlocal/UnsafeTest.java new file mode 100644 index 0000000..0bb44f9 --- /dev/null +++ b/src/main/java/org/javacore/thread/threadlocal/UnsafeTest.java @@ -0,0 +1,23 @@ +package org.javacore.thread.threadlocal; + +import java.util.concurrent.TimeUnit; + +/** + * 描述:可以看到线程每个有不同的启动时间,但是结束时间会有相同. + * Created by bysocket on 16/3/8. + */ +public class UnsafeTest { + public static void main(String[] args) { + UnsafeTask task = new UnsafeTask(); + for (int i = 0 ; i < 10; i++) { + Thread thread = new Thread(task); + thread.start(); + + try { + TimeUnit.SECONDS.sleep(2); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } +} diff --git a/src/main/java/org/javacore/thread/uncaughtexp/ExceptionHadler.java b/src/main/java/org/javacore/thread/uncaughtexp/ExceptionHadler.java new file mode 100644 index 0000000..a60c42c --- /dev/null +++ b/src/main/java/org/javacore/thread/uncaughtexp/ExceptionHadler.java @@ -0,0 +1,19 @@ +package org.javacore.thread.uncaughtexp; + +import java.lang.Thread.UncaughtExceptionHandler; + +/** + * 描述:处理运行时异常的类 + * Created by bysocket on 16/3/4. + */ +public class ExceptionHadler implements UncaughtExceptionHandler{ + @Override + public void uncaughtException(Thread t, Throwable e) { + System.out.printf("An exception has been captured\n"); + System.out.printf("Thread: %s\n",t.getId()); + System.out.printf("Exception: %s: %s\n",e.getClass().getName(),e.getMessage()); + System.out.printf("Stack Trace: \n"); + e.printStackTrace(System.out); + System.out.printf("Thread status: %s\n",t.getState()); + } +} diff --git a/src/main/java/org/javacore/thread/uncaughtexp/UncaughtTask.java b/src/main/java/org/javacore/thread/uncaughtexp/UncaughtTask.java new file mode 100644 index 0000000..696a822 --- /dev/null +++ b/src/main/java/org/javacore/thread/uncaughtexp/UncaughtTask.java @@ -0,0 +1,12 @@ +package org.javacore.thread.uncaughtexp; + +/** + * 描述:抛出运行时异常的线程类 + * Created by bysocket on 16/3/4. + */ +public class UncaughtTask implements Runnable { + @Override + public void run() { + int numero = Integer.parseInt("TTTT"); + } +} diff --git a/src/main/java/org/javacore/thread/uncaughtexp/UncaughtTest.java b/src/main/java/org/javacore/thread/uncaughtexp/UncaughtTest.java new file mode 100644 index 0000000..059f074 --- /dev/null +++ b/src/main/java/org/javacore/thread/uncaughtexp/UncaughtTest.java @@ -0,0 +1,14 @@ +package org.javacore.thread.uncaughtexp; + +/** + * 描述:实现异常类Test + * Created by bysocket on 16/3/4. + */ +public class UncaughtTest { + public static void main(String[] args) { + UncaughtTask uncaughtTask = new UncaughtTask(); + Thread thread = new Thread(uncaughtTask); + thread.setUncaughtExceptionHandler(new ExceptionHadler()); + thread.start(); + } +} diff --git a/src/main/java/org/javacore/time/Duration.java b/src/main/java/org/javacore/time/Duration.java new file mode 100644 index 0000000..9d23c31 --- /dev/null +++ b/src/main/java/org/javacore/time/Duration.java @@ -0,0 +1,319 @@ +package org.javacore.time; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Maps; + +import java.io.Serializable; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Title: Duration + * Create Date: 2016-08-26 15:43 + * Description: Duration unit, consisting of length and time unit. + * Simple time convert. + * + * @author Yufan + */ +public class Duration implements Serializable { + private static final long serialVersionUID = 3898309763927286550L; + + /** + * A duration of Long.MAX_VALUE Days + */ + public static final Duration INFINITE = new Duration(); + + /** + * Common time pattern + */ + private static final Pattern PATTERN = Pattern.compile( + "(∞|inf|infinite)|" + "(([\\d]+)[\\s]*(" + "ns|nanosecond(s)?|" + "us|microsecond(s)?|" + "ms|millisecond(s)?|" + "s|second(s)?|" + + "m|min|mins|minute(s)?|" + "h|hour(s)?|" + "d|day(s)?" + "))"); + private static final Map SUFFIXES;
+
+ public final long length;
+ public final TimeUnit timeUnit;
+ public final boolean finite;
+
+ static {
+ SUFFIXES = Maps.newHashMapWithExpectedSize(32);
+
+ SUFFIXES.put("ns", TimeUnit.NANOSECONDS);
+ SUFFIXES.put("nanosecond", TimeUnit.NANOSECONDS);
+ SUFFIXES.put("nanoseconds", TimeUnit.NANOSECONDS);
+
+ SUFFIXES.put("us", TimeUnit.MICROSECONDS);
+ SUFFIXES.put("microsecond", TimeUnit.MICROSECONDS);
+ SUFFIXES.put("microseconds", TimeUnit.MICROSECONDS);
+
+ SUFFIXES.put("ms", TimeUnit.MILLISECONDS);
+ SUFFIXES.put("millisecond", TimeUnit.MILLISECONDS);
+ SUFFIXES.put("milliseconds", TimeUnit.MILLISECONDS);
+
+ SUFFIXES.put("s", TimeUnit.SECONDS);
+ SUFFIXES.put("second", TimeUnit.SECONDS);
+ SUFFIXES.put("seconds", TimeUnit.SECONDS);
+
+ SUFFIXES.put("m", TimeUnit.MINUTES);
+ SUFFIXES.put("min", TimeUnit.MINUTES);
+ SUFFIXES.put("mins", TimeUnit.MINUTES);
+ SUFFIXES.put("minute", TimeUnit.MINUTES);
+ SUFFIXES.put("minutes", TimeUnit.MINUTES);
+
+ SUFFIXES.put("h", TimeUnit.HOURS);
+ SUFFIXES.put("hour", TimeUnit.HOURS);
+ SUFFIXES.put("hours", TimeUnit.HOURS);
+
+ SUFFIXES.put("d", TimeUnit.DAYS);
+ SUFFIXES.put("day", TimeUnit.DAYS);
+ SUFFIXES.put("days", TimeUnit.DAYS);
+ }
+
+ /**
+ * Infinite constructor.
+ */
+ private Duration() {
+ finite = false;
+ this.length = Long.MAX_VALUE;
+ this.timeUnit = TimeUnit.DAYS;
+ }
+
+ private Duration(long length, TimeUnit timeUnit) {
+ this.length = length;
+ this.timeUnit = Preconditions.checkNotNull(timeUnit, "timeUnit");
+ finite = !(length == Long.MAX_VALUE && TimeUnit.DAYS.equals(timeUnit));
+ }
+
+ /**
+ * Returns the Duration converted to days.
+ */
+ public long toDays() {
+ return TimeUnit.DAYS.convert(length, timeUnit);
+ }
+
+ /**
+ * Returns the Duration converted to hours.
+ */
+ public long toHours() {
+ return TimeUnit.HOURS.convert(length, timeUnit);
+ }
+
+ /**
+ * Returns the Duration converted to microseconds.
+ */
+ public long toMicros() {
+ return TimeUnit.MICROSECONDS.convert(length, timeUnit);
+ }
+
+ /**
+ * Returns the Duration converted to microseconds.
+ */
+ public long toMicroseconds() {
+ return TimeUnit.MICROSECONDS.convert(length, timeUnit);
+ }
+
+ /**
+ * Returns the Duration converted to milliseconds.
+ */
+ public long toMillis() {
+ return TimeUnit.MILLISECONDS.convert(length, timeUnit);
+ }
+
+ /**
+ * Returns the Duration converted to milliseconds.
+ */
+ public long toMilliseconds() {
+ return TimeUnit.MILLISECONDS.convert(length, timeUnit);
+ }
+
+ /**
+ * Returns the Duration converted to minutes.
+ */
+ public long toMins() {
+ return TimeUnit.MINUTES.convert(length, timeUnit);
+ }
+
+ /**
+ * Returns the Duration converted to minutes.
+ */
+ public long toMinutes() {
+ return TimeUnit.MINUTES.convert(length, timeUnit);
+ }
+
+ /**
+ * Returns the Duration converted to nanoseconds.
+ */
+ public long toNanos() {
+ return TimeUnit.NANOSECONDS.convert(length, timeUnit);
+ }
+
+ /**
+ * Returns the Duration converted to nanoseconds.
+ */
+ public long toNanoseconds() {
+ return TimeUnit.NANOSECONDS.convert(length, timeUnit);
+ }
+
+ /**
+ * Returns the Duration converted to seconds.
+ */
+ public long toSeconds() {
+ return TimeUnit.SECONDS.convert(length, timeUnit);
+ }
+
+ /**
+ * Returns the Duration converted to seconds.
+ */
+ public long toSecs() {
+ return TimeUnit.SECONDS.convert(length, timeUnit);
+ }
+
+ /**
+ * Returns a Duration of {@code count} days.
+ */
+ public static Duration days(long count) {
+ return new Duration(count, TimeUnit.DAYS);
+ }
+
+ /**
+ * Returns a Duration of {@code count} hours.
+ */
+ public static Duration hours(long count) {
+ return new Duration(count, TimeUnit.HOURS);
+ }
+
+ /**
+ * Returns an infinite duration of Long.MAX_VALUE days.
+ */
+ public static Duration inf() {
+ return INFINITE;
+ }
+
+ /**
+ * Returns an infinite duration of Long.MAX_VALUE days.
+ */
+ public static Duration infinite() { // NOSONAR
+ return INFINITE;
+ }
+
+ /**
+ * Returns a Duration of {@code count} microseconds.
+ */
+ public static Duration microseconds(long count) {
+ return new Duration(count, TimeUnit.MICROSECONDS);
+ }
+
+ /**
+ * Returns a Duration of {@code count} milliseconds.
+ */
+ public static Duration millis(long count) {
+ return new Duration(count, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Returns a Duration of {@code count} milliseconds.
+ */
+ public static Duration milliseconds(long count) {
+ return new Duration(count, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * Returns a Duration of {@code count} minutes.
+ */
+ public static Duration mins(long count) {
+ return new Duration(count, TimeUnit.MINUTES);
+ }
+
+ /**
+ * Returns a Duration of {@code count} minutes.
+ */
+ public static Duration minutes(long count) {
+ return new Duration(count, TimeUnit.MINUTES);
+ }
+
+ /**
+ * Returns a Duration of {@code count} nanoseconds.
+ */
+ public static Duration nanos(long count) {
+ return new Duration(count, TimeUnit.NANOSECONDS);
+ }
+
+ /**
+ * Returns a Duration of {@code count} nanoseconds.
+ */
+ public static Duration nanoseconds(long count) {
+ return new Duration(count, TimeUnit.NANOSECONDS);
+ }
+
+ /**
+ * Returns a Duration of {@code count} {@code unit}s.
+ */
+ public static Duration of(long count, TimeUnit unit) {
+ return new Duration(count, unit);
+ }
+
+ /**
+ * Returns a Duration from the parsed {@code duration}. Example:
+ *
+ *
+ * 5 s
+ * 5 seconds
+ * 10m
+ * 10 minutes
+ *
+ */
+ public static Duration of(String duration) {
+ Matcher matcher = PATTERN.matcher(duration);
+ if (!matcher.matches()) {
+ throw new IllegalArgumentException("Invalid duration: " + duration);
+ }
+
+ if (matcher.group(1) != null) {
+ return INFINITE;
+ } else {
+ String unit = matcher.group(4);
+ String value = matcher.group(3);
+ return new Duration(Long.parseLong(value), SUFFIXES.get(unit));
+ }
+ }
+
+ /**
+ * Returns a Duration of {@code count} seconds.
+ */
+ public static Duration seconds(long count) {
+ return new Duration(count, TimeUnit.SECONDS);
+ }
+
+ /**
+ * Returns a Duration of {@code count} seconds.
+ */
+ public static Duration secs(long count) {
+ return new Duration(count, TimeUnit.SECONDS);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ } else if ((obj == null) || (getClass() != obj.getClass())) {
+ return false;
+ }
+ final Duration duration = (Duration) obj;
+ return (length == duration.length) && (timeUnit == duration.timeUnit);
+ }
+
+ @Override
+ public int hashCode() {
+ return (31 * (int) (length ^ (length>>> 32))) + timeUnit.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ String units = timeUnit.toString().toLowerCase();
+ if (length == 1)
+ units = units.substring(0, units.length() - 1);
+ return Long.toString(length) + ' ' + units;
+ }
+}
diff --git a/src/main/java/org/javacore/time/TimeUtil.java b/src/main/java/org/javacore/time/TimeUtil.java
new file mode 100644
index 0000000..34d0011
--- /dev/null
+++ b/src/main/java/org/javacore/time/TimeUtil.java
@@ -0,0 +1,118 @@
+package org.javacore.time;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * 基于 JDK 8 time包的时间工具类
+ *
+ * Created by bysocket on 16/8/23.
+ */
+public final class TimeUtil {
+
+ /**
+ * 获取默认时间格式: yyyy-MM-dd HH:mm:ss
+ */
+ private static final DateTimeFormatter DEFAULT_DATETIME_FORMATTER = TimeFormat.LONG_DATE_PATTERN_LINE.formatter;
+
+ private TimeUtil() {
+ // no construct function
+ }
+
+ /**
+ * String 转时间
+ *
+ * @param timeStr
+ * @return
+ */
+ public static LocalDateTime parseTime(String timeStr) {
+ return LocalDateTime.parse(timeStr, DEFAULT_DATETIME_FORMATTER);
+ }
+
+ /**
+ * String 转时间
+ *
+ * @param timeStr
+ * @param format 时间格式
+ * @return
+ */
+ public static LocalDateTime parseTime(String timeStr, TimeFormat format) {
+ return LocalDateTime.parse(timeStr, format.formatter);
+ }
+
+ /**
+ * 时间转 String
+ *
+ * @param time
+ * @return
+ */
+ public static String parseTime(LocalDateTime time) {
+ return DEFAULT_DATETIME_FORMATTER.format(time);
+ }
+
+ /**
+ * 时间转 String
+ *
+ * @param time
+ * @param format 时间格式
+ * @return
+ */
+ public static String parseTime(LocalDateTime time, TimeFormat format) {
+ return format.formatter.format(time);
+ }
+
+ /**
+ * 获取当前时间
+ *
+ * @return
+ */
+ public static String getCurrentDatetime() {
+ return DEFAULT_DATETIME_FORMATTER.format(LocalDateTime.now());
+ }
+
+ /**
+ * 获取当前时间
+ *
+ * @param format 时间格式
+ * @return
+ */
+ public static String getCurrentDatetime(TimeFormat format) {
+ return format.formatter.format(LocalDateTime.now());
+ }
+
+ /**
+ * 时间格式
+ */
+ public enum TimeFormat {
+
+ /**
+ * 短时间格式
+ */
+ SHORT_DATE_PATTERN_LINE("yyyy-MM-dd"),
+ SHORT_DATE_PATTERN_SLASH("yyyy/MM/dd"),
+ SHORT_DATE_PATTERN_DOUBLE_SLASH("yyyy\\MM\\dd"),
+ SHORT_DATE_PATTERN_NONE("yyyyMMdd"),
+
+ /**
+ * 长时间格式
+ */
+ LONG_DATE_PATTERN_LINE("yyyy-MM-dd HH:mm:ss"),
+ LONG_DATE_PATTERN_SLASH("yyyy/MM/dd HH:mm:ss"),
+ LONG_DATE_PATTERN_DOUBLE_SLASH("yyyy\\MM\\dd HH:mm:ss"),
+ LONG_DATE_PATTERN_NONE("yyyyMMdd HH:mm:ss"),
+
+ /**
+ * 长时间格式 带毫秒
+ */
+ LONG_DATE_PATTERN_WITH_MILSEC_LINE("yyyy-MM-dd HH:mm:ss.SSS"),
+ LONG_DATE_PATTERN_WITH_MILSEC_SLASH("yyyy/MM/dd HH:mm:ss.SSS"),
+ LONG_DATE_PATTERN_WITH_MILSEC_DOUBLE_SLASH("yyyy\\MM\\dd HH:mm:ss.SSS"),
+ LONG_DATE_PATTERN_WITH_MILSEC_NONE("yyyyMMdd HH:mm:ss.SSS");
+
+ private transient DateTimeFormatter formatter;
+
+ TimeFormat(String pattern) {
+ formatter = DateTimeFormatter.ofPattern(pattern);
+ }
+ }
+}
diff --git a/src/main/java/org/jee/rpc/EchoService.java b/src/main/java/org/jee/rpc/EchoService.java
new file mode 100644
index 0000000..e329980
--- /dev/null
+++ b/src/main/java/org/jee/rpc/EchoService.java
@@ -0,0 +1,9 @@
+package org.jee.rpc;
+
+/**
+ * 描述:服务Echo接口类
+ * Created by bysocket on 16/2/28.
+ */
+public interface EchoService {
+ String echo(String ping);
+}
diff --git a/src/main/java/org/jee/rpc/EchoServiceImpl.java b/src/main/java/org/jee/rpc/EchoServiceImpl.java
new file mode 100644
index 0000000..0403ea9
--- /dev/null
+++ b/src/main/java/org/jee/rpc/EchoServiceImpl.java
@@ -0,0 +1,12 @@
+package org.jee.rpc;
+
+/**
+ * 描述:服务Echo实现类
+ * Created by bysocket on 16/2/28.
+ */
+public class EchoServiceImpl implements EchoService {
+ @Override
+ public String echo(String ping) {
+ return ping != null ? ping + " --> I am ok." : "I am ok.";
+ }
+}
diff --git a/src/main/java/org/jee/rpc/RpcExporter.java b/src/main/java/org/jee/rpc/RpcExporter.java
new file mode 100644
index 0000000..567e187
--- /dev/null
+++ b/src/main/java/org/jee/rpc/RpcExporter.java
@@ -0,0 +1,107 @@
+package org.jee.rpc;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Method;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
+/**
+ * 描述:RPC服务发布者
+ * Created by bysocket on 16/2/28.
+ */
+public class RpcExporter {
+ // 创建线程池
+ static Executor executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
+
+ public static void exporter(String hostName,int port) throws IOException {
+ ServerSocket serverSocket = new ServerSocket();
+ serverSocket.bind(new InetSocketAddress(hostName,port));
+ try {
+ while (true) {
+ /**
+ * 监听Client的TCP连接,将其封装成Task,由线程池执行.
+ */
+ executor.execute(new ExporterTask(serverSocket.accept()));
+ }
+ } finally {
+ serverSocket.close();
+ }
+ }
+
+ /**
+ * 线程Task:
+ * 1. 将客户端发送的二进制流反序列化成对象,反射调用服务实现者,获取执行结果
+ * 2. 将执行结果对象反序列化,通过Socket发送给客户端
+ * 3. 远程服务调用完成之后,释放Socket等连接资源,防止句柄泄漏
+ */
+ private static class ExporterTask implements Runnable {
+ Socket client = null;
+ public ExporterTask(Socket accept) {
+ this.client = accept;
+ }
+
+ @Override
+ public void run() {
+ ObjectInputStream input = null;
+ ObjectOutputStream output = null;
+ try {
+ // 对象输入流
+ input = new ObjectInputStream(client.getInputStream());
+
+ // 获取接口名
+ String interfaceName = input.readUTF();
+ // 获取方法名
+ String methodName = input.readUTF();
+ // 获取方法的参数数组
+ Class>[] paramTypes = (Class>[]) input.readObject();
+ // 获取传入参数对象数组
+ Object[] arguments = (Object[]) input.readObject();
+
+ // 获取服务对象类
+ Class> service = Class.forName(interfaceName);
+ // 获取服务方法
+ Method method = service.getMethod(methodName,paramTypes);
+ // 获取服务方法返回对象
+ Object result = method.invoke(service.newInstance(),arguments);
+
+ // 对象输出流
+ output = new ObjectOutputStream(client.getOutputStream());
+ output.writeObject(result);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ // 关闭流的操作
+ if (output != null) {
+ try {
+ output.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (input != null) {
+ try {
+ input.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (client != null) {
+ try {
+ client.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/jee/rpc/RpcImporter.java b/src/main/java/org/jee/rpc/RpcImporter.java
new file mode 100644
index 0000000..c4359fc
--- /dev/null
+++ b/src/main/java/org/jee/rpc/RpcImporter.java
@@ -0,0 +1,60 @@
+package org.jee.rpc;
+
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+
+/**
+ * 描述:Rpc本地服务代理类
+ * 1. 将本地接口调用转化为JDK的动态调用,在动态调用中实现接口的远程调用
+ * 2. 创建Socket客户端,根据制定地址连接远程服务提供者
+ * 3. 将远程服务调用所需的接口类,方法名,参数列表等编码后发送给服务提供者
+ * 4. 同步阻塞等待服务端返回应答,获取应答后返回
+ * Created by bysocket on 16/2/29.
+ */
+public class RpcImporter {
+ public S importer(final Class> serviceClass, final InetSocketAddress address) {
+ // JDK动态代理,实现接口的远程调用
+ return (S) Proxy.newProxyInstance(serviceClass.getClassLoader(),
+ new Class>[]{serviceClass.getInterfaces()[0]},
+ new InvocationHandler() {
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ Socket socket = null;
+ ObjectOutputStream output = null;
+ ObjectInputStream input = null;
+
+ try {
+ // 连接远程服务提供者
+ socket = new Socket();
+ socket.connect(address);
+
+ // 对象输出流
+ output = new ObjectOutputStream(socket.getOutputStream());
+ output.writeUTF(serviceClass.getName());
+ output.writeUTF(method.getName());
+ output.writeObject(method.getParameterTypes());
+ output.writeObject(args);
+
+ input = new ObjectInputStream(socket.getInputStream());
+ return input.readObject();
+ } finally {
+ if (socket != null) {
+ socket.close();
+ }
+ if (output != null) {
+ output.close();
+ }
+ if (input != null) {
+ input.close();
+ }
+ }
+ }
+ });
+ }
+}
diff --git a/src/main/java/org/jee/rpc/RpcTest.java b/src/main/java/org/jee/rpc/RpcTest.java
new file mode 100644
index 0000000..07fef5b
--- /dev/null
+++ b/src/main/java/org/jee/rpc/RpcTest.java
@@ -0,0 +1,31 @@
+package org.jee.rpc;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+
+/**
+ * 描述:RPC测试代码类
+ * Created by bysocket on 16/2/29.
+ */
+public class RpcTest {
+ public static void main(String[] args) {
+ // 启动服务提供者
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ RpcExporter.exporter("localhost",8088);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }).start();
+
+ // 创建服务本地代理
+ RpcImporter importer = new RpcImporter();
+
+ // 从服务本地代理获取服务对象类
+ EchoService echo = importer.importer(EchoServiceImpl.class,new InetSocketAddress("localhost",8088));
+ System.out.println(echo.echo("Are you OK?"));
+ }
+}
diff --git "a/src/main/resources/collections/347円273円230円345円233円2761円.vsdx" "b/src/main/resources/collections/347円273円230円345円233円2761円.vsdx"
new file mode 100644
index 0000000..9e2e96b
Binary files /dev/null and "b/src/main/resources/collections/347円273円230円345円233円2761円.vsdx" differ
diff --git a/src/main/resources/io/file/file.vsdx b/src/main/resources/io/file/file.vsdx
new file mode 100644
index 0000000..ba81c60
Binary files /dev/null and b/src/main/resources/io/file/file.vsdx differ
diff --git a/src/main/resources/io/file/file01.vsdx b/src/main/resources/io/file/file01.vsdx
new file mode 100644
index 0000000..ffd88e1
Binary files /dev/null and b/src/main/resources/io/file/file01.vsdx differ
diff --git a/src/main/resources/io/file/filenameFilter.vsdx b/src/main/resources/io/file/filenameFilter.vsdx
new file mode 100644
index 0000000..911aab8
Binary files /dev/null and b/src/main/resources/io/file/filenameFilter.vsdx differ
diff --git a/src/main/resources/io/iostream/iostream.vsdx b/src/main/resources/io/iostream/iostream.vsdx
new file mode 100644
index 0000000..b4bf02f
Binary files /dev/null and b/src/main/resources/io/iostream/iostream.vsdx differ
diff --git a/test/org/javacore/io/DirectoryTest.java b/src/test/java/org/javacore/io/DirectoryTest.java
similarity index 100%
rename from test/org/javacore/io/DirectoryTest.java
rename to src/test/java/org/javacore/io/DirectoryTest.java
diff --git a/src/test/java/org/javacore/param/Param.java b/src/test/java/org/javacore/param/Param.java
new file mode 100644
index 0000000..f3ed2a9
--- /dev/null
+++ b/src/test/java/org/javacore/param/Param.java
@@ -0,0 +1,57 @@
+package org.javacore.param;
+
+/**
+ * Created by bysocket on 16/7/18.
+ */
+public class Param {
+ Integer id;
+
+ String name;
+
+ Integer age;
+
+ String sex;
+
+ Integer isBeautiful;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Integer getAge() {
+ return age;
+ }
+
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+
+ public String getSex() {
+ return sex;
+ }
+
+ public void setSex(String sex) {
+ this.sex = sex;
+ }
+
+ public Integer getIsBeautiful() {
+ return isBeautiful;
+ }
+
+ public void setIsBeautiful(Integer isBeautiful) {
+ this.isBeautiful = isBeautiful;
+ }
+
+}
diff --git a/src/test/java/org/javacore/param/ParamService.java b/src/test/java/org/javacore/param/ParamService.java
new file mode 100644
index 0000000..cd87d29
--- /dev/null
+++ b/src/test/java/org/javacore/param/ParamService.java
@@ -0,0 +1,21 @@
+package org.javacore.param;
+
+/**
+ * Created by bysocket on 16/7/18.
+ */
+public class ParamService {
+
+ public void test01(Param param) {
+ Integer id = param.getId();
+ String sex = param.getSex();
+ String name = param.getName();
+ Integer age = param.getAge();
+ Integer isBeautiful = param.getIsBeautiful();
+
+
+ }
+
+ public void test02(Integer id,String sex,String name,Integer age,Integer isBeautiful) {
+
+ }
+}
diff --git a/src/test/java/org/javacore/param/ParamTest.java b/src/test/java/org/javacore/param/ParamTest.java
new file mode 100644
index 0000000..3cd5bfb
--- /dev/null
+++ b/src/test/java/org/javacore/param/ParamTest.java
@@ -0,0 +1,32 @@
+package org.javacore.param;
+
+import java.util.Date;
+
+/**
+ * Created by bysocket on 16/7/18.
+ */
+public class ParamTest {
+
+ public static void main(String[] args) {
+ ParamService p = new ParamService();
+
+ Date start = new Date();
+ for (int i = 1 ; i < 1000000; i++) {
+ p.test02(1,"2","3",4,5);
+ }
+ Date end = new Date();
+ System.out.println("ParamService.test02() : " + (end.getTime() - start.getTime()) );
+ Date start2 = new Date();
+ for (int i = 1 ; i < 100000; i++) {
+ Param param = new Param();
+ param.setId(1);
+ param.setAge(2);
+ param.setIsBeautiful(1);
+ param.setName("2");
+ param.setSex("2");
+ p.test01(param);
+ }
+ Date end2 = new Date();
+ System.out.println("ParamService.test01() : " + (end2.getTime() - start2.getTime()) );
+ }
+}
diff --git a/test/org/javacore/thread/MyRunnableTest.java b/src/test/java/org/javacore/thread/MyRunnableTest.java
similarity index 100%
rename from test/org/javacore/thread/MyRunnableTest.java
rename to src/test/java/org/javacore/thread/MyRunnableTest.java
diff --git a/test/org/javacore/thread/MyThreadTest.java b/src/test/java/org/javacore/thread/MyThreadTest.java
similarity index 100%
rename from test/org/javacore/thread/MyThreadTest.java
rename to src/test/java/org/javacore/thread/MyThreadTest.java
diff --git a/src/test/java/org/javacore/time/DurationTest.java b/src/test/java/org/javacore/time/DurationTest.java
new file mode 100644
index 0000000..2778646
--- /dev/null
+++ b/src/test/java/org/javacore/time/DurationTest.java
@@ -0,0 +1,61 @@
+package org.javacore.time;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+public class DurationTest {
+ @Test
+ public void testCombineTimeUtil() throws Exception {
+ Assert.assertEquals(Duration.days(1).toMilliseconds(), 24 * 3600 * 1000);
+ Assert.assertEquals(24 * 3600 * 1000 * 3, Duration.days(3).toMilliseconds());
+ Assert.assertEquals(7 * 24 * 3600 * 1000 / 1000, Duration.days(7).toSeconds());
+ }
+
+ @Test
+ public void testValidDurationStrings() throws Exception {
+ Assert.assertEquals(Duration.of("5ns"), Duration.nanoseconds(5));
+ Assert.assertEquals(Duration.of("5microsecond"), Duration.microseconds(5));
+ Assert.assertEquals(Duration.of("5milliseconds"), Duration.millis(5));
+ Assert.assertEquals(Duration.of("5 seconds"), Duration.seconds(5));
+ Assert.assertEquals(Duration.of("5 minutes"), Duration.mins(5));
+ Assert.assertEquals(Duration.of("5 hours"), Duration.hours(5));
+ Assert.assertEquals(Duration.of("5 days"), Duration.days(5));
+ Assert.assertEquals(Duration.of("inf"), Duration.inf());
+ Assert.assertEquals(Duration.of("infinite"), Duration.inf());
+ Assert.assertEquals(Duration.of("∞"), Duration.infinite());
+
+ // Interesting value but legal nevertheless
+ Assert.assertEquals(Duration.of("0s"), Duration.seconds(0));
+ }
+
+ private void testInvalidDurationString(String duration) {
+ try {
+ Duration.of(duration);
+ fail("Duration string '" + duration + "' should not parse correctly.");
+ } catch (IllegalArgumentException iae) {
+ // Expected
+ }
+ }
+
+ @Test
+ public void testInvalidDurationStrings() {
+ testInvalidDurationString("foobar");
+ testInvalidDurationString("ms3");
+ testInvalidDurationString("34 lightyears");
+ testInvalidDurationString("34 seconds a day");
+ testInvalidDurationString("5 days a week");
+ testInvalidDurationString("");
+ testInvalidDurationString("2");
+ testInvalidDurationString("ns");
+ }
+
+ @Test
+ public void testReplaceOldTimeUtils() {
+ final int HOUR = 1000 * 60 * 60;
+ long randomTimestamp = (long) (Math.random() * 400000000L) + 100000;
+ Assert.assertEquals(randomTimestamp / HOUR, Duration.millis(randomTimestamp).toHours());
+ Assert.assertEquals(randomTimestamp / 1000, Duration.millis(randomTimestamp).toSeconds());
+ }
+}
diff --git a/src/test/java/org/javacore/time/InstantTest.java b/src/test/java/org/javacore/time/InstantTest.java
new file mode 100644
index 0000000..4df282f
--- /dev/null
+++ b/src/test/java/org/javacore/time/InstantTest.java
@@ -0,0 +1,24 @@
+package org.javacore.time;
+
+import java.time.Instant;
+
+/**
+ * 瞬间类 Instant
+ *
+ * Created by bysocket on 16/7/12.
+ */
+public class InstantTest {
+ public static void main(String[] args) {
+ // 获取现在的时间
+ Instant now = Instant.now();
+ System.out.println(now);
+
+ // 1000000000 年 12月 31日
+ Instant max = Instant.MAX;
+ System.out.println(max);
+
+ // 10亿年前
+ Instant min = Instant.MIN;
+ System.out.println(min);
+ }
+}
diff --git a/src/test/java/org/javacore/time/LocalDateTest.java b/src/test/java/org/javacore/time/LocalDateTest.java
new file mode 100644
index 0000000..bba3aa8
--- /dev/null
+++ b/src/test/java/org/javacore/time/LocalDateTest.java
@@ -0,0 +1,29 @@
+package org.javacore.time;
+
+import java.time.LocalDate;
+
+/**
+ * Created by bysocket on 16/8/23.
+ */
+public class LocalDateTest {
+ public static void main(String[] args) {
+ // 今天的日期
+ LocalDate localDate = LocalDate.now();
+
+ System.out.println("今天:" + localDate);
+
+ // 年
+ System.out.println("年:" + localDate.getYear());
+ // 月
+ System.out.println("月:" + localDate.getMonth());
+ System.out.println("月:" + localDate.getMonth());
+ // 星期
+ System.out.println("今天是星期" + localDate.getDayOfWeek());
+
+ // 距离
+ // 年
+ System.out.println("今天是今年的第" + localDate.getDayOfYear() + "天");
+ // 月
+ System.out.println("今天是这个月的第" + localDate.getDayOfMonth() + "天");
+ }
+}
diff --git a/src/test/java/org/javacore/time/LocalDateTest1.java b/src/test/java/org/javacore/time/LocalDateTest1.java
new file mode 100644
index 0000000..15467b8
--- /dev/null
+++ b/src/test/java/org/javacore/time/LocalDateTest1.java
@@ -0,0 +1,18 @@
+package org.javacore.time;
+
+import java.time.LocalDate;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by bysocket on 16/8/23.
+ */
+public class LocalDateTest1 {
+ public static void main(String[] args) throws InterruptedException {
+ LocalDate start = LocalDate.now();
+ TimeUnit.SECONDS.sleep(3);
+ LocalDate end = LocalDate.now();
+
+ System.out.println(start.isAfter(end));
+ System.out.println(start.isBefore(end));
+ }
+}
diff --git a/src/test/java/org/javacore/time/LocalDateTest2.java b/src/test/java/org/javacore/time/LocalDateTest2.java
new file mode 100644
index 0000000..66bc101
--- /dev/null
+++ b/src/test/java/org/javacore/time/LocalDateTest2.java
@@ -0,0 +1,17 @@
+package org.javacore.time;
+
+import java.time.LocalDate;
+
+/**
+ * 计算BYSocket的生日是今年的第几天
+ *
+ * Created by bysocket on 16/8/23.
+ */
+public class LocalDateTest2 {
+ public static void main(String[] args) {
+ LocalDate birthdayDate = LocalDate.of(2016,5,2);
+ System.out.println("BYSocket的生日是今年的第" + birthdayDate.getDayOfYear() + "天");
+ // 明年的生日
+ System.out.println(birthdayDate.plusYears(1));
+ }
+}
diff --git a/src/test/java/org/javacore/time/PlayDuration.java b/src/test/java/org/javacore/time/PlayDuration.java
new file mode 100644
index 0000000..827b56c
--- /dev/null
+++ b/src/test/java/org/javacore/time/PlayDuration.java
@@ -0,0 +1,34 @@
+package org.javacore.time;
+
+import java.time.Duration;
+import java.time.Instant;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 持续时间类 Duration
+ *
+ * Created by bysocket on 16/8/23.
+ */
+public class PlayDuration {
+ public static void main(String[] args) throws InterruptedException {
+ Instant start = Instant.now();
+ TimeUnit.SECONDS.sleep(3);
+ Instant end = Instant.now();
+
+ // 获取持续时间
+ Duration timeElapsed = Duration.between(start,end);
+ System.out.println(timeElapsed.toMillis());// 毫秒
+ System.out.println(timeElapsed.toNanos());// 纳
+
+ Instant start1 = Instant.now();
+ TimeUnit.SECONDS.sleep(2);
+ Instant end1 = Instant.now();
+
+ // 获取持续时间
+ Duration timeElapsed1 = Duration.between(start1,end1);
+
+ // 添加操作
+ Duration all = timeElapsed.plus(timeElapsed1);
+ System.out.println(all.toMillis());// 毫秒
+ }
+}
diff --git a/src/test/java/org/javacore/time/TimeUtilTest.java b/src/test/java/org/javacore/time/TimeUtilTest.java
new file mode 100644
index 0000000..3716481
--- /dev/null
+++ b/src/test/java/org/javacore/time/TimeUtilTest.java
@@ -0,0 +1,41 @@
+package org.javacore.time;
+
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+import java.time.LocalDateTime;
+
+import static org.javacore.time.TimeUtil.TimeFormat.LONG_DATE_PATTERN_DOUBLE_SLASH;
+import static org.javacore.time.TimeUtil.TimeFormat.LONG_DATE_PATTERN_SLASH;
+import static org.junit.Assert.assertEquals;
+
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class TimeUtilTest {
+
+ @Test
+ public void testParseSpecificTimeStringByUsingDefaultPattern() throws Exception {
+ LocalDateTime expectedDateTime = LocalDateTime.of(2014, 11, 11, 10, 11, 11);
+ LocalDateTime parsedTime = TimeUtil.parseTime("2014-11-11 10:11:11");
+ assertEquals(expectedDateTime, parsedTime);
+ }
+
+ @Test
+ public void testParseSpecificTimeStringUsingTimeFormat() throws Exception {
+ LocalDateTime expectedDateTime = LocalDateTime.of(2014, 11, 11, 10, 11, 11);
+ LocalDateTime parsedTime = TimeUtil.parseTime("2014/11/11 10:11:11", LONG_DATE_PATTERN_SLASH);
+ assertEquals(expectedDateTime, parsedTime);
+ }
+
+ @Test
+ public void testParseLocalDateTimeByUsingDefaultFormatter() throws Exception {
+ LocalDateTime time = LocalDateTime.of(2014, 11, 11, 10, 11, 11);
+ assertEquals(TimeUtil.parseTime(time), "2014-11-11 10:11:11");
+ }
+
+ @Test
+ public void testParseLocalDateTimeByUsingTimeFormat() throws Exception {
+ LocalDateTime time = LocalDateTime.of(2014, 11, 11, 10, 11, 11);
+ assertEquals(TimeUtil.parseTime(time, LONG_DATE_PATTERN_DOUBLE_SLASH), "2014\11円\11円 10:11:11");
+ }
+}