RDF 中的术语

RDF Dataset : represents a collection of graphs. An RDF Dataset comprises one graph, the default graph, which does not have a name, and zero or more named graphs, where each named graph is identified by an IRI.

By javafuns on June 9, 2010 at 16:39 · Views: 188 · Permalink · RSS · Leave a comment
Categorized in: HTTP / WEB · Tagged with: 

java.util.concurrent 中的 Executor

java.util.concurrent 中包含有线程池的实现, 以及 Runnable 和 Callable 的执行器(Executor), 通过使用线程池, 可减少创建线程的开销.

以下介绍按照编写线程的通常顺序进行.

一. Executors 类: 线程执行器的工厂类

这个类提供了很多工厂方法, 可用来获取 Executor、ExecutorService、ScheduledExecutorService、ThreadFactory 和 Callable 类, 所以通常情况下, 应该通过本类来取得这些接口的实例.  对于 Executor、ExecutorService、ScheduledExecutorService、ThreadFactory 和 Callable 等接口或类, 将在下面介绍.

比如:

创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。

创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。

创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。

也分别可以创建单线程执行程序, 如:

创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。

创建一个单线程执行程序,它可安排在给定延迟后运行命令或者定期地执行。

二. Executor 接口: 线程执行器

执行已提交的 Runnable 任务的对象。此接口提供一种将任务提交与每个任务将如何运行的机制(包括线程使用的细节、调度等)分离开来的方法。

在未来某个时间执行给定的命令。

通常使用 Executor 而不是显式地创建线程。例如,可能会使用以下方法,而不是为一组任务中的每个任务调用 new Thread(new(RunnableTask())).start()

 Executor executor = anExecutor;
 executor.execute(new RunnableTask1());
 executor.execute(new RunnableTask2());
 ...

不过,Executor 接口并没有严格地要求执行是异步的。在最简单的情况下,执行程序可以在调用者的线程中立即运行已提交的任务:

 class DirectExecutor implements Executor {
     public void execute(Runnable r) {
         r.run();
     }
 }

更常见的是,任务是在某个不是调用者线程的线程中执行的。以下执行程序将为每个任务生成一个新线程。

 class ThreadPerTaskExecutor implements Executor {
     public void execute(Runnable r) {
         new Thread(r).start();
     }
 }

三. ExecutorService、ScheduledExecutorService 接口: 线程池

(一) 中提到的 ExecutorService、ScheduledExecutorService 都是 Executor 的子接口, ExecutorService、ScheduledExecutorService 也提供了自己所特有的方法声明:

四. ThreadPoolExecutor、ScheduledThreadPoolExecutor 类: 线程池具体实现

这是线程池(ExecutorService、ScheduledExecutorService)的具体实现. 如非必要, 请使用 Executors 创建一个线程池.  此类提供了一些 Hook 方法, 所以大部分该类的子类都扩展了这些 hook 方法.

By javafuns on May 7, 2010 at 17:53 · Views: 225 · Permalink · RSS · Leave a comment
Categorized in: Java · Tagged with: ,

java.util.concurrent 中的 Callable 和 Future

Callable 和 Future 也是用于线程编程的两个新的 API.

Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。

Callable 接口只有一个方法声明: V call() throws Exception

Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。计算完成后只能使用 get 方法来获取结果,如有必要,计算完成前可以阻塞此方法。取消则由 cancel 方法来执行。还提供了其他方法,以确定任务是正常完成还是被取消了。一旦计算完成,就不能再取消计算。如果为了可取消性而使用 Future 但又不提供可用的结果,则可以声明 Future<?> 形式类型、并返回 null 作为底层任务的结果。

可取消的异步计算。利用开始和取消计算的方法、查询计算是否完成的方法和获取计算结果的方法,此类提供了对 Future 的基本实现。仅在计算完成时才能获取结果;如果计算尚未完成,则阻塞 get 方法。一旦计算完成,就不能再重新开始或取消计算。

可使用 FutureTask 包装 Callable 或 Runnable 对象。因为 FutureTask 实现了 Runnable,所以可将 FutureTask 提交给 Executor 执行。

  1. FutureTask(Callable<V> callable) 创建一个 FutureTask,一旦运行就执行给定的 Callable。
  2. FutureTask(Runnable runnable, V result) 创建一个 FutureTask,一旦运行就执行给定的 Runnable,并安排成功完成时 get 返回给定的结果 。

例子1:

FutureTask<String> future =
new FutureTask<String>(new Callable<String>() {
public String call() {
return searcher.search(target);
}});
executor.execute(future);

例子2:

Callable<Integer> myCompution = ...;
FutureTask<Integer> task = new FutureTask<Integer>(myCompution);
Thread t = new Thread(task);  // it's a Runnable
t.start();
...
Integer result = task.get();  // It's a future

实现了 Runnable 和 Future 接口.

By javafuns on May 6, 2010 at 22:36 · Views: 203 · Permalink · RSS · Leave a comment
Categorized in: Java · Tagged with: ,

New Synchronization Mechanism in Java Threads

对于绝大部分程序员来说,实现线程同步的最常用手段是使用 synchronized 关键字。在 Java 5.0 中,又增加了新的线程加锁手段,那就是 java.util.concurrent.locks 中的lock。这些锁具有与 synchronized 关键字相同的语义,但使用起来更直观,也更加强大。

1. Lock

以 ReentrantLock 为例:(Java Doc 中的例子)

class X {
  private final ReentrantLock lock = new ReentrantLock();
  // ...

  public void m() {
    lock.lock();  // block until condition holds
    try {
      // ... method body
    } finally {
      lock.unlock()
    }
  }
}

看起来是不是更直观呢?

ReentrantLock 顾名思义,可多次加锁,每锁定一次,持锁计数加 1,在多次释放锁后,持锁计数变为 0,此时锁才会被释放掉。

2. Condition

不单是如此,每个 lock 可使用多个 Condition,这些 Condition 同样具有与 Object 的 wait()、notify()、notifyAll() 方法同样的语义。

再以 Java Document 中的代码为例:

class BoundedBuffer {
   final Lock lock = new ReentrantLock();
   final Condition notFull  = lock.newCondition();
   final Condition notEmpty = lock.newCondition(); 

   final Object[] items = new Object[100];
   int putptr, takeptr, count;

   public void put(Object x) throws InterruptedException {
     lock.lock();
     try {
       while (count == items.length)
         notFull.await();
       items[putptr] = x;
       if (++putptr == items.length) putptr = 0;
       ++count;
       notEmpty.signal();
     } finally {
       lock.unlock();
     }
   }

   public Object take() throws InterruptedException {
     lock.lock();
     try {
       while (count == 0)
         notEmpty.await();
       Object x = items[takeptr];
       if (++takeptr == items.length) takeptr = 0;
       --count;
       notFull.signal();
       return x;
     } finally {
       lock.unlock();
     }
   }
 }

在使用时必须要特别小心,一定要在 finally 块中释放锁。

3. Lock types

Lock 可分为 公平(fair)锁 和 不公平(unfair)锁。

公平锁:要求线程按照顺序获取锁

不公平锁:线程间可以讨价还价,进而占有锁

不公平锁的性能要好于公平锁,甚至 synchronized 也要好于公平锁。除非特殊原因,否则请使用不公平锁。

4. 结论

新的 Lock API 提供了更多的特性,更好的性能,但是,专家们建议,不要轻易丢弃 synchronized,除非你有能力驾驭新的 Lock 框架。

参考文档

1. Java Document
2. JDK 5.0 中更灵活、更具可伸缩性的锁定机制

By javafuns on April 29, 2010 at 15:22 · Views: 418 · Permalink · RSS · Leave a comment
Categorized in: Java · Tagged with: ,

优秀程序员的45个习惯

态度篇

1. 做实事

不要抱怨,发牢骚,指责他人,找出问题所在,想办法解决。对问题和错误,要勇于承担。

2. 欲速则不达

用小聪明、权宜之计解决问题,求快而不顾代码质量,会给项目留下要命的死角。

3. 对事不对人

就事论事,明智、真诚、虚心地讨论问题,提出创新方案。

4. 排除万难,奋勇前进

勇气往往是克服困难的唯一方法。

学习篇

5. 跟踪变化

新技术层出不穷并不可怕。坚持学习新技术,读书,读技术杂志,参加技术活动,与人交流。要多理解新词背后的所以然,把握技术大趋势,将新技术用于产 品开发要谨慎。 Read more »

By javafuns on March 22, 2010 at 13:33 · Views: 266 · Permalink · RSS · Leave a comment
Categorized in: Uncategorized · Tagged with: 

The differences between Date and Timestamp

java.sql.Timestampjava.util.Date 的一个子类,但切不可将 java.sql.Timestamp 作为一个 java.util.Date 来使用,因为这样会造成一些时间上的误差。
其原因在于:
java.sql.Timestamp 使用一个 java.util.Date 保存整数秒,其它作为纳秒保存在另一个变量里。

另外,也可以看出,java.sql.Timestamp 的(纳秒级)精确度要大于 java.util.Date(毫秒级)。

By javafuns on March 19, 2010 at 13:23 · Views: 372 · Permalink · RSS · Leave a comment
Categorized in: Java · Tagged with: 

Android 应用开发系列(二)基础知识-Activity和Task

前面提及过,一个 activity 可启动另一个,包括定义在不同程序里的 activity。举例来说,假定你想让用户显示某地的一个街道地图。现在已经有一个 activity 能干这个事情,所以你的 activity 所要做的就是把必须的信息放到 Intent 对象并传递给该 activity 的 startActivity() 方法。地图 viewer 会显示这个地图。当用户按了 BACK 键,你的 activity 会再次出现在屏幕上。

对用户来说,就好像这个地图就是跟你的 activity 是同一个程序的一部分一样,尽管它其实是定义在另一个程序里并且运行在那个程序的进程里。Android 通过让这两个 acitivity 在同一个 task 里来保持这种用户体验。简单来说,一个 task 就是使得用户感觉如何一个程序(”application”)的东东。它是一组相关的 activity, 排列在一个 stack 里。stack 的根 activity 是开始这个 task 的 activity — 典型地,是用户在程序启动器里所选择的那个 activity。在 stack 顶部的 activity 是当前正在运行的那个 — 拥有焦点、响应用户动作。当一个 activity 启动另一个 activity,新 activity 被压入 stack 中;它称为正在运行的 activity。之前的 activity 仍在 stack 里。当用户按下 BACK 键,当前 activity 从 stack 中弹出,之前的 activity 恢复为正在运行的 activity。

stack 容纳对象,因此如果一个 task 打开有同一 Activity 子类的多个实例 — 例如,多个地图 viewers — stack 会给每个实例一个独立的条目(entry)。stack 里的 Activities 永远都不会重新排列,只是压入和弹出。

一个 task 是一个 activity 栈(stack),而不是一个类或者定义在 manifest 文件里的一个 element。因此,没有办法可以独立于 task 的 activities 而给这个 task 设置值。给整个 task 的值都是在它的根 activity 里设置的。例如,下一章节会谈到 “affinity of a task”;that value is read from the affinity set for the task’s root activity.

task 里的所有 activities 作为一个单位一起移动。整个 task(整个 activity stack)可被移到前台或者移动后台。例如,假设当前 task 有 4 个  activities 在它的 stack 里 — 3 个在当前活跃 activity 之下。用户按下 HOME 键,转到程序启动器,选择一个新程序(实际上是一个新的 task)。当前这个 task 转入后台,而新 task 的根 activity 被显示出来。然后,过了一小会儿,用户回退到 home 屏幕,再次选择之前的程序(之前的 task)。这个有全部 4 个 activities 在 stack 里的 task 转到前台。当用户按下 BACK 键,屏幕不会再显示用户刚刚离开的的那个 activity(之前 task 的根 activity)。反而是,该 stack 顶部的 activity 被移除,stack 里的前一个 activity被显示出来。

刚才描述行为是 activities 和 tasks 的默认行为。但是有办法可以改变这个默认行为的几乎所有方面。tasks 与 activities 的关联,task 中 activity 的行为,是通过(启动了该 activity 的)Intent 对象里的 flags 与(定义于 manifest 文件里的该 activity 的) <activity> element 的 attributes 两者之间交互作用而控制的。请求者和响应者就发生的事情都要有说明(Both requester and respondent have a say in what happens)。

在这点上,主要的 Intent flags 有:

FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
FLAG_ACTIVITY_SINGLE_TOP

主要的 <activity> attributes 有:

taskAffinity
launchMode
allowTaskReparenting
clearTaskOnLaunch
alwaysRetainTaskState
finishOnTaskLaunch

接下来的章节讲述这些 flags 和 attributes 有何用处,它们如何交互,在使用时需要注意什么。

By javafuns on March 10, 2010 at 17:29 · Views: 395 · Permalink · RSS · Leave a comment
Categorized in: Mobile · Tagged with: ,

Android 应用开发系列(二)基础知识-程序组件

Android 最终是需要打包成 .apk 文件,一个 .apk 文件就是一个 Android 程序,用户下载这种文件并安装到自己的设备上。

两个应用之间也可以共享同一 user ID,在这种情况下,它们就可以看到彼此的文件。为了保存系统资源,使用相同 ID 的程序也可以协调起来运行于同一 Linux 进程,共享同一 VM。

程序组件

Android 的一个特色是,一个程序可以使用另一个程序的元素(element),只要该程序允许。与其它大部分系统上的程序不同,Android 程序不是有单一入口点(例如没有 main()方法)。反之,它们所拥有的组件,系统可以根据需要实例化并运行。有 4 种类型组件:

Activity

Activity 用于表现可视化的用户界面。例如,短信程序可能有一个 activity 用于显示一组可供选择的联系人,第二个 activity 撰写短消息用于发送给选中的联系人,另一些 activity 可用来查看以前的短消息或更改设置。虽然它们共同构成了完整的用户界面,但每个 activity 都是独立的。由当前 activity 启动下一个 activity,即可从一个 activity 转移到另一个。

每个 activity 都有一个默认 window。window 里的内容由具有层次结构的 view 实现,这些 view 都继承自 View 类。每个 view 都控制着 window 内的一块矩形区域。父 view 包含并负责组织它的孩子 view 的布局。叶子 views(位于层次结构中底部的 view)在它所控制的矩形内绘制,并响应用户对该区域的操作。Android 已经有很多拿来即可用的 views — 包括 buttons, text fields, scroll bars, menu items, check boxes, 等等。

view 层次结构通过 Activity.setContentView() 方法放置到 activity 的 window 内。content view 是层次结构中的根 View 对象。

Services

service 运行于后台,每个 service 都继承 Service 类。以媒体播放器为例,用户希望播放后,转而干其它事情,这时就需要在后台启动并运行一个 playback service。

跟 activity 和其它组件一样,service 运行于程序进程的主线程中。因此,它们不会阻塞其它组件或者用户界面,它们常常会为 time-consuming 任务产生另外一个线程(像音乐 playback)。

Broadcast receivers

broadcast receiver 用于接收和对 broadcast 通知作出反应,如电池电量快没了,时区被改了,等。

程序可以有任意数量的 broadcast receivers 用来响应任何它认为重要的通知。所有 receivers 需继承 BroadcastReceiver 类。

Broadcast receivers 不显示用户界面。但是,它们可能会启动一个 activity 响应它们接收到的信息,或者它们可能使用 NotificationManager 通知用户。通知可使用多种方式来引起用户的注意 — 闪烁一下背光灯,震动设备,播放声音,等等。最常见的,是在状态栏上放置一个永久图标,用户可以打开来获取消息。

Content providers

content provider 负责提供特定的一组程序数据给其它程序。数据可以存储在文件系统,SQLite database,或者任何其它可用方式。content provider 继承 ContentProvider 类并提供方法实现,以使得其它程序获取或存储它所支持的数据类型的数据。但是,程序不会直接调用这些方法。它们使用 ContentResolver 对象并调用该对象的方法。一个 ContentResolver 可以跟其它任何 content provider 交互;与 provider 一起管理工序间通讯。

每当有请求需要特定组件处理时,Android 会确保该组件的程序进程已经在运行,否则会在必要时启动它,确保该组件有实例可用,否则会在必要时创建实例。 Read more »

By javafuns on March 7, 2010 at 22:08 · Views: 395 · Permalink · RSS · Leave a comment
Categorized in: Mobile · Tagged with: ,
  • Highest Rated

  • My PicasaPhotos

    IMG_0619.JPG

    IMG_0673.JPG

    IMG_0591.JPG

  • RSS My del.icio.us

  • My RSS