Archive

Posts Tagged ‘Java’

Java 多线程:捕捉线程中逃逸的异常

February 24th, 2011 leeing No comments

由于线程的本质特性,不能捕获从线程中抛出的异常,一但异常跳出run方法,就会直接输出到控制台。在Java5中,可以用Executor来解决这个问题。

Thread.UncaughtExceptionHandler接口允许在每个Thread对象上附着一个异常处理器,它的uncaughtException方法会在线程因未捕获的异常而临近死亡时被调用。我们可以创建一个ThreadFactory,它将在每个新创建的Thread对象上附着Thread.UncaughtExceptionHanlder。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

class ExceptionThread2 implements Runnable{

    public void run() {
        Thread t = Thread.currentThread();
        System.out.println("run() by "+t);
        System.out.println("eh = "+t.getUncaughtExceptionHandler());
        throw new RuntimeException();
    }

}

class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{

    public void uncaughtException(Thread t, Throwable e) {
        System.out.println("caught "+e);
    }
}

class HandlerThreadFactory implements ThreadFactory{

    public Thread newThread(Runnable r) {
        System.out.println(this + " creating new Thread");
        Thread t = new Thread(r);
        System.out.println("Created :"+t);
        t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
        System.out.println("eh = "+t.getUncaughtExceptionHandler());
        return t;
    }

}
public class CaptureUncaughtException {
    public static void main(String[] args) {
        ExecutorService exec = Executors.newCachedThreadPool(new HandlerThreadFactory());
        exec.execute(new ExceptionThread2());
        exec.shutdown();
    }
}

Read more…

Categories: Java, 多线程 Tags: ,

Java IO 简介

January 18th, 2011 leeing No comments

Java.io包是用术语流(stream)来定义的,流是有序的数据序列,它有一个源(输入流)或一个目的地(输出流) ,它代表任何有能力产生数据的数据源对象或者有能力接收数据的接收端对象,它屏蔽了实际I/O设备中处理数据的细节。

Java.nio包是用术语Channel 和buffer来定义I/O的。缓冲区是可以从中读取或写入的数据存储(类似于数组),通道表示的是能够执行I/O操作的实体的连接,这些实体包括缓冲区,文件和套接字。NIO和OIO的区别主要在于Channel允许不阻塞的I/O操作和可中断的阻塞操作,这对于高吞吐量的服务器应用是至关重要的。

Java.net包是基于对套接字的使用,用一种基于流,或者基于通道的模型提供了对网络I/O的特殊支持。

Java.io中的字符流,字符是指16位的UTF-16字符。

关闭流可以释放该流可能使用过的资源(如文件描述符),这些资源在不再使用时尽快回收;而如果某个流未被显式地关闭,则继续持有这些资源。流类可以定义finalize方法,但是通常在完成流的操作以后,就应该将其关闭。如果流已经被关闭,之后在其上操作会触发IOException,而关闭一个已经被关闭了的流则不会有任何的影响。(即流可以重复关闭,但不能在关闭之后继续使用

所有的字节流都具有相同的同步策略和并发行为。

下面主要说明一些特别要注意的方法:

InputStream

public abstract int read() throws IOException

这个是唯一需要重写的方法,用以读取数据的一个单个字节,并返回0~255之间的整数,如果已经达到流的末尾,则将返回-1。注意,这个方法将发生阻塞直到可获取输入,到达流的末尾,或者抛出异常。这个方法返回的是一个int而不是byte值,因为它需要返回所的有效的字节值加上一个表示末尾的标志值,这就要求标志值要超出byte的范围,所以就采用了更大的int。注意 System.in就是InputStream类型的。

OutputStream

public abstract void write(int b) throws IOException

将b作为一个字节写入,由于是int类型,只有此整数的最低8位会被写入,此方法将阻塞直至字节写入完成。

InputStream和OuputStream分别只要求子类实现其read和write方法,因为其它read,write方法都是在此基础上定义的,大多数流都可以通过覆盖read或write方法来提高性能,而OutputStream中的flush和close方法的默认实现通常都需要在特定的流中进行恰当的覆盖,尤其是被缓冲的流,可能需要在关闭的时候进行刷新。

设计Reader和Writer类继承层次主要是为了国际化,因为16位的Unicode用于字符国际化,所以添加这两个类层次就是为了在所有的I/O操作中支持Unicode,此外,新类库的设计使得它的操作比旧类库要快。在应用中,最明智的做法应该是:尽量尝试使用Reader和Writer,一旦程序代码无法成功编译,才使用面向字节的类库。例如,java.util.zip就是只面向字节的。

Read more…

Categories: Java Tags: ,

用户访问行为,齐普夫分布及其 Java 实现

May 18th, 2010 leeing 2 comments

Zipf定律是文献计量学的重要定律之一,它和罗特卡定律、布拉德福定律一起被并称为文献计量学的三大定律。

对于CDN的内容管理,也近似符合Zipf 定律,就是大家常说对于内容的访问遵循80/20原则,也就是20%的内容,会占有80%的访问量。

zipf law

zipf law

这里 r 表示一个单词的出现频率的排名,P(r)表示排名为r的单词的出现频率.

(单词频率分布中 C约等于0.1, a约等于1)

后人将这个分布称为zipf distribution,中文名称为齐普夫分布或Zeta 分布。这是一个离散事件分布,广泛应用于语言学,保险学,网络模拟,以及对稀疏事件的建模中。

它表明在英语单词中,只有极少数的词被经常使用,而绝大多数词很少被使用。实际上,包括汉语在内的许多国家的语言都有这种特点。这个定律后来在很多领域得到了同样的验证,包括网站的访问者数量、城镇的大小和每个国家公司的数量。。这个定理也在很多分布里面得到了验证,比如人们的收入,互联网的网站数量和访问比例,互联网内容和访问比例(其他分布两个常数有所不同,a越大,分布越密集,对于VOD来说某些时候符合双zipf分布)。

比起枯燥的公式,图表更具有说服力,下面是用三百个严格符合zipf 分布的数据点描绘成的图,其中横轴表示排名,纵轴表示访问的频率,分别使用线性坐标和对数坐标表示:

zipf distribution

zipf distribution

可以看到对数坐标下是一条完美的直线。

Read more…

Categories: CDN, Java Tags: , , ,

Netbeans 性能调优及加速

May 5th, 2010 leeing 2 comments

NetBeans  安装目录下的 netbeans.conf  文件中的 netbeans_default_options  能够对 NetBeans 的启动,运行以及编译的速度产生很大的影响,恰当地设值可以让 NetBeans 的性能有大幅提升,当然如果设置的值过高也能导致 NetBeans 无法启动。

我的内存是 2GB 的,netbeans_default-options 设置为以下的参数,运行速度很快,在这里做个备份供以后参考。

netbeans_default_options="-J-Dfile.encoding=UTF-8 -J-XX:PermSize=128m -J-XX:MaxPermSize=256m -J-Xmx1024m  -J-Duser.language=en -J-client -J-Xverify:none -J-Xss2m -J-Xms512m -J-Dapple.laf.useScreenMenuBar=true -J-Dsun.java2d.noddraw=true -J-XX:+UseConcMarkSweepGC -J-XX:+CMSClassUnloadingEnabled -J-XX:+CMSPermGenSweepingEnabled"
Categories: Java Tags: ,

Swing : 将 System.out 重定向到 JTextArea 和 JTextPane

April 30th, 2010 leeing 1 comment

最近在用Swing 来编写图形用户界面,其中一个需求就是将System.out.println 的输出重定向到JTextArea组件中,刚开始使用的是《Java 标准输出重定向到GUI 》里的代码,但是在后台需要大量计算的时候,界面出现无响应的情况。后来又经过一番搜索,在 blogspot 找到了一篇文章: 《 Redirecting System.out and System.err to JTextPane or JTextArea》 ( 被墙了),可以实现实时输出的功能,不会出现缓慢的情况。

在 Swing 中,如果想将System.out和System.err 重定向到 JTextPane或者JTextArea,只需要覆盖OutputStream中的write() 方法来将文件附加到 text pane中。

JTextArea 版本:

  private void updateTextArea(final String text) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        textArea.append(text);
      }
    });
  }

  private void redirectSystemStreams() {
    OutputStream out = new OutputStream() {
      @Override
      public void write(int b) throws IOException {
        updateTextArea(String.valueOf((char) b));
      }

      @Override
      public void write(byte[] b, int off, int len) throws IOException {
        updateTextArea(new String(b, off, len));
      }

      @Override
      public void write(byte[] b) throws IOException {
        write(b, 0, b.length);
      }
    };

    System.setOut(new PrintStream(out, true));
    System.setErr(new PrintStream(out, true));
  }

Read more…

Categories: Java Tags: ,