JDK5中的一个亮点就是将Doug Lea的并发库引入到Java标准库中。Doug Lea确实是一个牛人,能教书,能出书,能编码,不过这在国外还是比较普遍的,而国内的教授们就相差太远了。
一般的服务器都需要线程池,比如Web、FTP等服务器,不过它们一般都自己实现了线程池,比如以前介绍过的Tomcat、Resin和Jetty等,现在有了JDK5,我们就没有必要重复造车轮了,直接使用就可以,何况使用也很方便,性能也非常高。 Continue reading »
JDK5中的一个亮点就是将Doug Lea的并发库引入到Java标准库中。Doug Lea确实是一个牛人,能教书,能出书,能编码,不过这在国外还是比较普遍的,而国内的教授们就相差太远了。
一般的服务器都需要线程池,比如Web、FTP等服务器,不过它们一般都自己实现了线程池,比如以前介绍过的Tomcat、Resin和Jetty等,现在有了JDK5,我们就没有必要重复造车轮了,直接使用就可以,何况使用也很方便,性能也非常高。 Continue reading »
notify()和notifyAll()都是Object对象用于通知处在等待该对象的线程的方法。两者的最大区别在于:
notifyAll使所有原来在该对象上等待被notify的线程统统退出wait的状态,变成等待该对象上的锁,一旦该对象被解锁,他们就会去竞争。
notify则文明得多他只是选择一个wait状态线程进行通知,并使它获得该对象上的锁,但不惊动其他同样在等待被该对象notify的线程们,当第一个线程运行完毕以后释放对象上的锁此时如果该对象没有再次使用notify语句,则即便该对象已经空闲,其他wait状态等待的线程由于没有得到该对象的通知,继续处在wait状态,直到这个对象发出一个notify或notifyAll,它们等待的是被notify或notifyAll,而不是锁。
下面是一个很好的例子:
import java.util.*;

class Widget…{}
class WidgetMaker extends Thread…{
List<Widget> finishedWidgets=new ArrayList<Widget>();
public void run()…{
try…{
while(true)…{
Thread.sleep(5000);//act busy
Widget w=new Widget();
//也就是说需要5秒钟才能新产生一个Widget,这决定了一定要用notify而不是notifyAll
//因为上面两行代码不是同步的,如果用notifyAll则所有线程都企图冲出wait状态
//第一个线程得到了锁,并取走了Widget(这个过程的时间小于5秒,新的Widget还没有生成)
//并且解开了锁,然后第二个线程获得锁(因为用了notifyAll其他线程不再等待notify语句
//,而是等待finishedWidgets上的锁,一旦锁放开了,他们就会竞争运行),运行
//finishedWidgets.remove(0),但是由于finishedWidgets现在还是空的,
//于是产生异常
//***********这就是为什么下面的那一句不能用notifyAll而是要用notify

synchronized(finishedWidgets)…{
finishedWidgets.add(w);
finishedWidgets.notify(); //这里只能是notify而不能是notifyAll
}
}
}
catch(InterruptedException e)…{}
}

public Widget waitForWidget()…{
synchronized(finishedWidgets)…{
if(finishedWidgets.size()==0)…{
try…{
finishedWidgets.wait();
}
catch(InterruptedException e)
…{}
}
return finishedWidgets.remove(0);
}
}
}
public class WidgetUser extends Thread…{
private WidgetMaker maker;
public WidgetUser(String name,WidgetMaker maker)…{
super(name);
this.maker=maker;
}
public void run()…{
Widget w=maker.waitForWidget();
System.out.println(getName()+“got a widget“);
}


public static void main(String[] args) …{
WidgetMaker maker=new WidgetMaker();
maker.start();
new WidgetUser(“Lenny“,maker).start();
new WidgetUser(“Moe“,maker).start();
new WidgetUser(“Curly“,maker).start();
}
}使用如下方法可以获得PrintJob的实例用于控制打印操作:
Toolkit.getPrintJob(Frame f, String jobtitle, Properties prop)
那么对于打印属性的设置可以通过对prop的属性设置来实现,打印属性包括:
awt.print.destination: 可以是”printer”或”file”
awt.print.printer: 打印机名
awt.print.fileName: 打印文件名
awt.print.numCopies: 打印份数
awt.print.options: 打印命令的打印选项
awt.print.orientation: 打印方向,可以是”portrait”或”landscape”
awt.print.paperSize: 纸张大小,可以是”letter”,”legal”,”executive”或”a4″
|
级别: 初级 2002 年 10 月 22 日
在我们的实际工作中,经常需要实现打印功能。但由于历史原因,Java提供的打印功能一直都比较弱。实际上最初的jdk根本不支持打印,直到jdk1.1才引入了很轻量的打印支持。所以,在以前用Java/Applet/JSP/Servlet设计的程序中,较复杂的打印都是通过调用ActiveX/OCX控件或者VB/VC程序来实现的,非常麻烦。实际上,SUN公司也一直致力于Java打印功能的完善,而Java2平台则终于有了一个健壮的打印模式的开端,该打印模式与Java2D图形包充分结合成一体。更令人鼓舞的是,新发布的jdk1.4则提供了一套完整的”Java 打印服务 API” (Java Print Service API),它对已有的打印功能是积极的补充。利用它,我们可以实现大部分实际应用需求,包括打印文字、图形、文件及打印预览等等。本文将通过一个具体的程序实例来说明如何设计Java打印程序以实现这些功能,并对不同版本的实现方法进行分析比较。希望大家能从中获取一些有益的提示。 Continue reading » Apr 20
Apr 15
线程是Java的一大特性,它可以是给定的指令序列、给定的方法中定义的变量或者一些共享数据(类一级的变量)。在Java中每个线程有自己的堆栈和程序计数器(PC),其中堆栈是用来跟踪线程的上下文(上下文是当线程执行到某处时,当前的局部变量的值),而程序计数器则用来跟踪当前线程正在执行的指令。 在通常情况下,一个线程不能访问另外一个线程的堆栈变量,而且这个线程必须处于如下状态之一:更多 Continue reading » Apr 12
使用DOM方式,Java解析XML基本步骤: Apr 10
如果项目有依赖的jar,那么要注意: 假设打包后名为A.jar 然后整理成如下目录结构 将所有依赖包都放入lib文件夹中,双击A.jar,程序就可以运行了。 Apr 10
FileDialog dialog=new FileDialog(frame,”加载文件”); public class FileListFilter implements FilenameFilter { public FileListFilter(String extension) { public boolean accept(File directory, String filename) { 但是但是, Apr 06
使用swing组件应注意代码顺序java Comments Off
总结: |