如果超过最大连接数,当然要让请求线程等待,要是等待线程过多嘛,系统允许的话可以增加最大连接。
下面是我平时常用的连接池基类,有不足之处,欢迎指正:
package mai.database.pool;
import mai.database.pool.ResourceException;
import java.util.*;public abstract class ResourcePool implements Runnable
{
protected final Vector availableResources=new Vector();
protected final Vector inUseResources=new Vector();
protected int maxResources;
private boolean waitOutTime;
private ResourceException error=null;
public ResourcePool()
{
this(10,true);
}
public ResourcePool(int max,boolean waitOutTime)
{
this.maxResources=max;
this.waitOutTime=waitOutTime;
}
public abstract Object createResource() throws ResourceException; public abstract boolean isAvailableResource(Object resource); public abstract void closeResource(Object resource); public Object getResource() throws ResourceException
{
return getResource(0);
} public Object getResource(long time) throws ResourceException
{
Object o=getFirstResource();
if(o==null)
{
if(countResources()<maxResources)
{
waitForAvailableResource();
return getResource();
}
else
{
if(waitOutTime)
{
try{
wait(time);
}
catch(Exception ex){System.out.println("资源已经用完,请等待...");}
return getResource();
}
throw new ResourceException("Maximum number of resources reached.Try again later.");
}
}
inUseResources.addElement(o);
return o;
}
private Object getFirstResource()
{
Object o=null;
if(availableResources.size()>0)
{
o=availableResources.firstElement();
availableResources.remove(0);
}
if(o!=null && !isAvailableResource(o))
o=getFirstResource();
return o;
}
public synchronized void run()
{
Object o=null;
try{
o=createResource();
}
catch(ResourceException e)
{ error=e;
notifyAll();
return;
}
availableResources.addElement(o);
notifyAll();
}
public synchronized void recycleResource(Object resource)
{
inUseResources.remove(resource);
availableResources.addElement(resource);
try{
notifyAll();
}
catch(Exception e)
{System.out.println("the current thread is not the owner of this object's monitor.");
}
}
private void waitForAvailableResource() throws ResourceException
{
Thread t=new Thread(this);
t.start();
try{
wait();
}
catch(Exception e)
{System.out.println("Method waitForAvailableResource's wait() is error");}
if(error!=null)
throw error;
}
private synchronized void closeResources(Vector v)
{
Iterator it=v.iterator();
while(it.hasNext())
closeResource(it.next());
}
public synchronized void showDown()
{
closeResources(availableResources);
closeResources(inUseResources);
availableResources.clear();
inUseResources.clear();
}
private int countResources()
{
return availableResources.size()+inUseResources.size();
}
}
下面是我平时常用的连接池基类,有不足之处,欢迎指正:
package mai.database.pool;
import mai.database.pool.ResourceException;
import java.util.*;public abstract class ResourcePool implements Runnable
{
protected final Vector availableResources=new Vector();
protected final Vector inUseResources=new Vector();
protected int maxResources;
private boolean waitOutTime;
private ResourceException error=null;
public ResourcePool()
{
this(10,true);
}
public ResourcePool(int max,boolean waitOutTime)
{
this.maxResources=max;
this.waitOutTime=waitOutTime;
}
public abstract Object createResource() throws ResourceException; public abstract boolean isAvailableResource(Object resource); public abstract void closeResource(Object resource); public Object getResource() throws ResourceException
{
return getResource(0);
} public Object getResource(long time) throws ResourceException
{
Object o=getFirstResource();
if(o==null)
{
if(countResources()<maxResources)
{
waitForAvailableResource();
return getResource();
}
else
{
if(waitOutTime)
{
try{
wait(time);
}
catch(Exception ex){System.out.println("资源已经用完,请等待...");}
return getResource();
}
throw new ResourceException("Maximum number of resources reached.Try again later.");
}
}
inUseResources.addElement(o);
return o;
}
private Object getFirstResource()
{
Object o=null;
if(availableResources.size()>0)
{
o=availableResources.firstElement();
availableResources.remove(0);
}
if(o!=null && !isAvailableResource(o))
o=getFirstResource();
return o;
}
public synchronized void run()
{
Object o=null;
try{
o=createResource();
}
catch(ResourceException e)
{ error=e;
notifyAll();
return;
}
availableResources.addElement(o);
notifyAll();
}
public synchronized void recycleResource(Object resource)
{
inUseResources.remove(resource);
availableResources.addElement(resource);
try{
notifyAll();
}
catch(Exception e)
{System.out.println("the current thread is not the owner of this object's monitor.");
}
}
private void waitForAvailableResource() throws ResourceException
{
Thread t=new Thread(this);
t.start();
try{
wait();
}
catch(Exception e)
{System.out.println("Method waitForAvailableResource's wait() is error");}
if(error!=null)
throw error;
}
private synchronized void closeResources(Vector v)
{
Iterator it=v.iterator();
while(it.hasNext())
closeResource(it.next());
}
public synchronized void showDown()
{
closeResources(availableResources);
closeResources(inUseResources);
availableResources.clear();
inUseResources.clear();
}
private int countResources()
{
return availableResources.size()+inUseResources.size();
}
}
解决方案 »
- 如何设计一个类
- 超简单的作业,怎么做?
- java连接数据库表时对其插入所遇到的困难,请各位高手伸出你们的帮助之手!
- java泛型
- 紧急求救,怎么写java swing发送数据到jsp上,然后jsp在返回一个ok,java swing在接受到,请高人赐教!!
- 怎么理解接口?
- JBoss提示以下信息:请问是出了什么问题?如何解决,谢谢各位老大了!
- 怎么得到一个命令行命令所产生的输出
- **各位好,一直搞delphi现在想学jbuilder,有什么好书介绍,能不能谈谈学习经验**
- 线程死锁。请前辈帮忙看一下。
- 如何禁止列表框多选
- ^_^ ^_^ 如何降低图像文件的颜色????????¥¥¥¥¥¥¥¥¥¥¥¥¥¥
谢谢回复,你的例子我看了。对线程处理很恰当,值得学习。能不能把实现类的代码也拿出来。我想看看,你整个连接池都解决到什么地步。另外对你这个连接池的调用也放出来吧。还有没有对上述3个问题有见解的评论,请多讨论。
凭心而论你的线程池的实现实在太简单了!
千万不要用于实际的应用!不安全!
1、同时用2个连接:我理解是这样客户端无论怎么调用这个全局的连接对象,在同一时间只能有一个连接取到数据。我不知道我理解的对不对,所谓同步最后总要归结为一个(指令)队列。所以这里同时使用连接的问题是在数据库当中解决的譬如oralce.
一个线程长时间占用:可以使该连接不同步(no synchronize),那么是不是一个线程无法独占这个连接了。当然,我认为有诸如你提到的这些问题以及事务、无意close等足以说明连接池的必要了。但如果小心的情况下有没有必须使用连接池的必要呢?请继续讨论2、这个问题Mai_520(网海茫茫,我也忙忙!)已经给了一个例子,我看了。除了未对等待线程管理外基本没什么可说的。给等待线程加入一个线程池管理就一定好么?我也想知道答案3、移植性差这点你说的对。
private void waitForAvailableResource() throws ResourceException
{
Thread t=new Thread(this);
t.start();
try{
wait();
另外不知道是不是没有定义释放资源的方法。 }我希望Mai_520把对这个连接池的调用过程放出来。让我们一目了然希望Norwaywoods()把自己好的例子也拿出来。:)
等待Norwaywoods()的结论,希望Norwaywoods()把那个Thread pool也引申的说一下,另外支持多CPU意味这什么呢?负载平衡么?如果是也把负载平衡相关原理及和thread pool和connection pool的关联说明一下。这个问题我也很想搞清楚,你可以由浅入深的来:)多谢其它同志有什么引申出来的问题,一并来讨论。
下面是我的实现类:
package mai.database.pool;
import mai.database.pool.*;
import java.sql.*;
import java.util.*;public class DatabaseConnPool extends ResourcePool
{
private String sDBDriver="";
private String url="";
private int initResources=5;
private boolean isLoadDriver=false;
private String user="",password=""; public DatabaseConnPool(String sdb,String url)
{
this(sdb,url,"","",10);
} public DatabaseConnPool(String sdb,String url,String user,String password,int maxResources)
{
this.sDBDriver=sdb;
this.url=url;
this.user=user;
this.password=password;
this.maxResources=maxResources;
System.out.println("[Connection Pool | inited Connection:"+initResources+" | max Connection:"+maxResources+"]");
for(int i=0;i<initResources;i++)
{
availableResources.addElement(createResource());
} } public Object createResource()
{
Connection conn=null;
if(!isLoadDriver)
{
try{
Class.forName(sDBDriver);
isLoadDriver=true;
}
catch(ClassNotFoundException e){System.out.println(e.getMessage());}
}
try{
conn=DriverManager.getConnection(url,user,password);
}catch(SQLException e){System.out.println(e.getMessage());}
return conn;
} public boolean isAvailableResource(Object resource)
{
Connection conn=(Connection)resource;
try{
if(!conn.isClosed())
return true;
}catch(SQLException e){System.out.println(e.getMessage());}
return false;
} public void closeResource(Object resource)
{
Connection conn=(Connection)resource;
try{
conn.close();
}
catch(SQLException e)
{System.out.println(e.getMessage());}
}
}
我对基类在创建一个资源对象时使用线程感觉到不理解,就是下面这个方法。
private void waitForAvailableResource() throws ResourceException
{
Thread t=new Thread(this);
t.start();
try{
wait();为什么使用线程来创建一个资源呢?
现在的容器基本上都是符合规范的,在进行连接池配置的时候只有一些细微的不同,也只是在deploy的时候略有不同,移植性的问题从何而来?
DB2数据库都没有问题,就是不知道如何连接远程的数据库,谢谢了!
/**
* ThreadPool.java
*/ 1: // uses ObjectFIFO
2:
3: public class ThreadPool extends Object {
4: private ObjectFIFO idleWorkers;
5: private ThreadPoolWorker[] workerList;
6:
7: public ThreadPool(int numberOfThreads) {
8: // make sure that it’s at least one
9: numberOfThreads = Math.max(1, numberOfThreads);
10:
11: idleWorkers = new ObjectFIFO(numberOfThreads);
12: workerList = new ThreadPoolWorker[numberOfThreads];
13:
14: for ( int i = 0; i < workerList.length; i++ ) {
15: workerList[i] = new ThreadPoolWorker(idleWorkers);
16: }
17: }
18:
19: public void execute(Runnable target) throws InterruptedException {
20: // block (forever) until a worker is available
21: ThreadPoolWorker worker = (ThreadPoolWorker) idleWorkers.remove();
22: worker.process(target);
23: }
24:
25: public void stopRequestIdleWorkers() {
26: try {
27: Object[] idle = idleWorkers.removeAll();
28: for ( int i = 0; i < idle.length; i++ ) {
29: ( (ThreadPoolWorker) idle[i] ).stopRequest();
30: }
31: } catch ( InterruptedException x ) {
32: Thread.currentThread().interrupt(); // re-assert
33: }
34: }
35:
36: public void stopRequestAllWorkers() {
37: // Stop the idle one’s first
38: // productive.
39: stopRequestIdleWorkers();
40:
41: // give the idle workers a quick chance to die
42: try { Thread.sleep(250); } catch ( InterruptedException x ) { }
43:
44: // Step through the list of ALL workers.
45: for ( int i = 0; i < workerList.length; i++ ) {
46: if ( workerList[i].isAlive() ) {
47: workerList[i].stopRequest();
48: }
49: }
50: }
51: }
/**
* ThreadPoolWorker.java
*/
1: // uses class ObjectFIFO
2:
3: public class ThreadPoolWorker extends Object {
4: private static int nextWorkerID = 0;
5:
6: private ObjectFIFO idleWorkers;
7: private int workerID;
8: private ObjectFIFO handoffBox;
9:
10: private Thread internalThread;
11: private volatile boolean noStopRequested;
12:
13: public ThreadPoolWorker(ObjectFIFO idleWorkers) {
14: this.idleWorkers = idleWorkers;
15:
16: workerID = getNextWorkerID();
17: handoffBox = new ObjectFIFO(1); // only one slot
18:
19: // just before returning, the thread should be created.
20: noStopRequested = true;
21:
22: Runnable r = new Runnable() {
23: public void run() {
24: try {
25: runWork();
26: } catch ( Exception x ) {
27: // in case ANY exception slips through
28: x.printStackTrace();
29: }
30: }
31: };
32:
33: internalThread = new Thread(r);
34: internalThread.start();
35: }
36:
37: public static synchronized int getNextWorkerID() {
38: // notice: sync’d at the class level to ensure uniqueness
39: int id = nextWorkerID;
40: nextWorkerID++;
41: return id;
42: }
43:
44: public void process(Runnable target) throws InterruptedException {
45: handoffBox.add(target);
46: }
47:
48: private void runWork() {
49: while ( noStopRequested ) {
50: try {
51: System.out.println(“workerID=” + workerID +
52: “, ready for work”);
53: // Worker is ready work. This will never block
54: // because the idleWorker FIFO queue has
55: // enough capacity for all the workers.
56: idleWorkers.add(this);
57:
58: // wait here until the server adds a request
59: Runnable r = (Runnable) handoffBox.remove();
60:
61: System.out.println(“workerID=” + workerID +
62: “, starting execution of new Runnable: “ + r);
63: runIt(r); // catches all exceptions
64: } catch ( InterruptedException x ) {
65: Thread.currentThread().interrupt(); // re-assert
66: }
67: }
68: }
69:
70: private void runIt(Runnable r) {
71: try {
72: r.run();
73: } catch ( Exception runex ) {
74: // catch any and all exceptions
75: System.err.println(”Uncaught exception fell through from run()”);
76: runex.printStackTrace();
77: } finally {
78: // Clear the interrupted flag (in case it comes back
79: // set) so that if the loop goes again, the
80: // handoffBox.remove() does not mistakenly
81: // throw an InterruptedException.
82: Thread.interrupted();
83: }
84: }
85:
86: public void stopRequest() {
87: System.out.println(“workerID=” + workerID +
88: “, stopRequest() received.”);
89: noStopRequested = false;
90: internalThread.interrupt();
91: }
92:
93: public boolean isAlive() {
94: return internalThread.isAlive();
95: }
96: }
这里还欠缺一个ObjectFIFO类,我就不贴了,反正就是一个先进先出队列。不过,也就是通过它来实现一些复杂的功能的。
实际应用中的好东西,决不是我辈想的那么简单!千万不要想当然,要努力学习!(呵呵,什么时候我也可以给别人忠告了)
import java.sql.*;
import java.util.*;
import java.util.Date;/**
* 数据库连接池
*/
public class DBConnectionManager implements Serializable
{
/**
* 连接池的实例
*/
static private DBConnectionManager instance;
/**
* 客户端个数
*/
static private int clients;
static private String output = "false"; /**
* 包含驱动程序的向量
*/
private Vector drivers = new Vector();
/**
* 写日志对象
*/
private PrintWriter log;
/**
* 存放各种数据库连接池的哈希表
*/
private Hashtable pools = new Hashtable(); /**
* 取得一个数据库连接池的实例
*/
static synchronized public DBConnectionManager getInstance()
{
if (instance == null)
{
instance = new DBConnectionManager();
instance.init();
}
clients++;
return instance;
} /**
* 释放一个数据库连接
*/
public void freeConnection(String name, Connection con)
{
DBConnectionPool pool = (DBConnectionPool) pools.get(name);
if (pool != null)
{
pool.freeConnection(con);
}
} /**
* 根据数据库名称取得一个连接
*/
public Connection getConnection(String name)
{
DBConnectionPool pool = (DBConnectionPool) pools.get(name);
if(pool != null)
{
Connection mycn = pool.getConnection();
return mycn;
}
return null;
} /**
* 根据数据库名称和延时时间取得一个连接
*/
public Connection getConnection(String name, long time)
{
DBConnectionPool pool = (DBConnectionPool) pools.get(name);
if (pool != null)
{
return pool.getConnection(time);
}
return null;
} /**
* 释放所有的连接
*/
public synchronized void release()
{
if (--clients != 0)
{
return;
}
Enumeration allPools = pools.elements();
while (allPools.hasMoreElements())
{
DBConnectionPool pool = (DBConnectionPool) allPools.nextElement();
pool.release();
}
Enumeration allDrivers = drivers.elements();
while (allDrivers.hasMoreElements())
{
Driver driver = (Driver) allDrivers.nextElement();
try
{
DriverManager.deregisterDriver(driver);
}catch (SQLException e)
{
e.printStackTrace();
}
}
} /**
* 根据配置属性建立数据库连接池
*/
private void createPools(Properties props)
{
Enumeration propNames = props.propertyNames();
while (propNames.hasMoreElements())
{
String name = (String) propNames.nextElement();
if (name.endsWith(".url"))
{
String poolName = name.substring(0, name.lastIndexOf("."));
String url = props.getProperty(poolName + ".url");
if (url == null)
{
continue;
}
String user = props.getProperty(poolName + ".user");
String password = props.getProperty(poolName + ".password");
String maxconn = props.getProperty(poolName + ".maxconn", "0");
int max;
try
{
max = Integer.valueOf(maxconn).intValue();
}catch (NumberFormatException e)
{
max = 50;
}
DBConnectionPool pool = new DBConnectionPool(poolName, url, user, password, max);
pools.put(poolName, pool);
}
}
} /**
*读取配置文件内容
*/
private void init()
{
//InputStream is = getClass().getResourceAsStream("/db.properties");
Properties dbProps = new Properties();
String filename = null;
try
{
String pwd = System.getProperty("pwd");
if(!pwd.endsWith(File.separator))
pwd += File.separator;
filename = pwd + "db.properties";
File file = new File(filename);
InputStream is = new FileInputStream(filename);
dbProps.load(is);
}catch (Exception e)
{
System.err.println("Can not read config file:" + filename);
return;
}
output = dbProps.getProperty("output","false");
String logFile = dbProps.getProperty("logfile", "DBConnectionManager.log");
try
{
log = new PrintWriter(new FileWriter(logFile, true), true);
}catch (IOException e)
{
System.err.println("can not open log file: " + logFile);
log = new PrintWriter(System.err);
}
loadDrivers(dbProps);
createPools(dbProps);
} /**
* 根据配置属性实例化驱动程序
*/
private void loadDrivers(Properties props)
{
String driverClasses = props.getProperty("drivers");
StringTokenizer st = new StringTokenizer(driverClasses);
while (st.hasMoreElements())
{
String driverClassName = st.nextToken().trim();
try
{
Driver driver = (Driver)Class.forName(driverClassName).newInstance();
DriverManager.registerDriver(driver);
drivers.addElement(driver);
}catch (Exception e)
{
}
}
} /**
* 输出日志
*/
private void log(String msg)
{
if(output.equals("true"))
log.println(new Date() + ": " + msg);
} private void log(Throwable e, String msg)
{
log.println(new Date() + ": " + msg);
e.printStackTrace(log);
} /**
* 内部连接池类
*/
class DBConnectionPool
{
private int checkedOut;
private Vector freeConnections = new Vector();
private int maxConn;
private String name;
private String password;
private String strurl;
private String user; /**
* @param name 数据库名
* @param strurl 数据库URL
* @param user 用户名
* @param password 密码
* @param maxConn 最大连接数
*/
public DBConnectionPool(String name, String strurl, String user, String password, int maxConn)
{
this.name = name;
this.strurl = strurl;
this.user = user;
this.password = password;
this.maxConn = maxConn;
} /**
* 释放连接
*/
public synchronized void freeConnection(Connection con)
{
freeConnections.addElement(con);
checkedOut--;
notifyAll();
} /**
* 取得一个空闲连接或者新建一个连接
*/
public synchronized Connection getConnection()
{
Connection con = null;
if(freeConnections.size() > 0)
{
con = (Connection) freeConnections.firstElement();
freeConnections.removeElementAt(0);
try
{
if (con.isClosed())
{
con = getConnection();
}
}catch (SQLException e)
{
e.printStackTrace();
con = getConnection();
}
}else
{
if (checkedOut >= maxConn)
{
maxConn++;
}
con = newConnection();
if (con != null)
{
checkedOut++;
}
}
return con;
} /**
* 根据指定延时取得一个连接
*/
public synchronized Connection getConnection(long timeout)
{
long startTime = new Date().getTime();
Connection con;
while ((con = getConnection()) == null)
{
try
{
wait(timeout);
}catch (InterruptedException e){}
if ((new Date().getTime() - startTime) >= timeout)
{
return null;
}
}
return con;
} /**
* 释放所有连接
*/
public synchronized void release()
{
Enumeration allConnections = freeConnections.elements();
while (allConnections.hasMoreElements())
{
Connection con = (Connection) allConnections.nextElement();
try
{
con.close();
}catch (SQLException e)
{
e.printStackTrace();
}
}
freeConnections.removeAllElements();
checkedOut = 0;
} /**
* 建立并取得新的连接
*/
private Connection newConnection()
{
Connection con = null;
try
{
if (user == null)
{
con = DriverManager.getConnection(strurl);
}else
{
con = DriverManager.getConnection(strurl, user, password);
}
}catch (SQLException e)
{
e.printStackTrace();
return null;
}
return con;
}
}
}
///:~
配置文件例子:
oracle.drivers=
oracle.url=
oracle.user=
oracle.password=
oracle.maxconn=
{
Thread t=new Thread(this);
t.start();
try{
wait();用一个新的线程去创建一个数据库连接,在run方法调用createResource(),
因为建立连接通常比较毫时,所以用一个新线程去做这些事,从而避免请求线程没有调用wait方法就被阻塞,这是不安全的。可能我没说太清楚:)
那么是不是Mai_520的例子那样不管是不是线程,到我这里都给你建立一个线程更合理呢。如果取数据的就是线程会不会出问题呢???我可能没说清楚。我对线程不是很精通。
反过来说,如果不是servlet这样启用线程来拿连接。又有什么同步问题呢?
没有线程,就没有同步。我的理解对么,请指正。
如果想学习连接池,也可以看看它的源代码,写得很精彩,看了后,保证会受益匪浅;下面是一个简单得例子(只是一个片断):
......
try
{
// load the PoolMan JDBC Driver
Class.forName("com.codestudio.sql.PoolMan").newInstance();
}
catch (Exception ex)
{
System.out.println("Could Not Find the PoolMan Driver. " +
"Is poolman.jar in your CLASSPATH?");
System.exit(0);
}
Connection con = DriverManager.getConnection("jdbc:poolman");
......
你的mai.database.pool.ResourceException;这个在哪阿muymuy(muy) 那个poolman从哪可以下载阿,在网上没有找到阿。
摘自:
Java Thread Programming
Paul Hyde
Copyright © 1999 Sams Publishing
1: public class ObjectFIFO extends Object {
2: private Object[] queue;
3: private int capacity;
4: private int size;
5: private int head;
6: private int tail;
7:
8: public ObjectFIFO(int cap) {
9: capacity = ( cap > 0 ) ? cap : 1; // at least 1
10: queue = new Object[capacity];
11: head = 0;
12: tail = 0;
13: size = 0;
14: }
15:
16: public int getCapacity() {
17: return capacity;
18: }
19:
20: public synchronized int getSize() {
21: return size;
22: }
23:
24: public synchronized boolean isEmpty() {
25: return ( size == 0 );
26: }
27:
28: public synchronized boolean isFull() {
29: return ( size == capacity );
30: }
31:
32: public synchronized void add(Object obj)
33: throws InterruptedException {
34:
35: waitWhileFull();
36:
37: queue[head] = obj;
38: head = ( head + 1 ) % capacity;
39: size++;
40:
41: notifyAll(); // let any waiting threads know about change
42: }
43:
44: public synchronized void addEach(Object[] list)
45: throws InterruptedException {
46:
47: //
48: // You might want to code a more efficient
49: // implementation here ... (see ByteFIFO.java)
50: //
51:
52: for ( int i = 0; i < list.length; i++ ) {
53: add(list[i]);
54: }
55: }
56:
57: public synchronized Object remove()
58: throws InterruptedException {
59:
60: waitWhileEmpty();
61:
62: Object obj = queue[tail];
63:
64: // don’t block GC by keeping unnecessary reference
65: queue[tail] = null;
66:
67: tail = ( tail + 1 ) % capacity;
68: size—;
69:
70: notifyAll(); // let any waiting threads know about change
71:
72: return obj;
73: }
74:
75: public synchronized Object[] removeAll()
76: throws InterruptedException {
77:
78: //
79: // You might want to code a more efficient
80: // implementation here ... (see ByteFIFO.java)
81: //
82:
83: Object[] list = new Object[size]; // use the current size
84:
85: for ( int i = 0; i < list.length; i++ ) {
86: list[i] = remove();
87: }
88:
89: // if FIFO was empty, a zero-length array is returned
90: return list;
91: }
92:
93: public synchronized Object[] removeAtLeastOne()
94: throws InterruptedException {
95:
96: waitWhileEmpty(); // wait for at least one to be in FIFO
97: return removeAll();
98: }
99:
Listing 18.4 Continued
100: public synchronized boolean waitUntilEmpty(long msTimeout)
101: throws InterruptedException {
102:
103: if ( msTimeout == 0L ) {
104: waitUntilEmpty(); // use other method
105: return true;
106: }
107:
108: // wait only for the specified amount of time
109: long endTime = System.currentTimeMillis() + msTimeout;
110: long msRemaining = msTimeout;
111:
112: while ( !isEmpty() && ( msRemaining > 0L ) ) {
113: wait(msRemaining);
114: msRemaining = endTime - System.currentTimeMillis();
115: }
116:
117: // May have timed out, or may have met condition,
118: // calc return value.
119: return isEmpty();
120: }
121:
122: public synchronized void waitUntilEmpty()
123: throws InterruptedException {
124:
125: while ( !isEmpty() ) {
126: wait();
127: }
128: }
129:
130: public synchronized void waitWhileEmpty()
131: throws InterruptedException {
132:
133: while ( isEmpty() ) {
134: wait();
135: }
136: }
137:
138: public synchronized void waitUntilFull()
139: throws InterruptedException {
140:
141: while ( !isFull() ) {
142: wait();
143: }
144: }
145:
146: public synchronized void waitWhileFull()
147: throws InterruptedException {
148:
149: while ( isFull() ) {
150: wait();
151: }
152: }
153: }