在java中使用线程很简单,只需要继承类Thread或者实现接口Runnable 即可。但是如果我们要使用线程挂起、恢复、停止的功能,如果直接使用Thread的suspend、resume、stop方法,就会出问题,原因是这几个方法在调用之后没有释放锁,从而会导致内存泄漏,jdk1.4中已经把这些方法给Deprecated掉了,所以不建议使用。那么怎样才能解决这个问题呢?也就是说要找到既能实现这些功能又不会导致内存泄漏的方法。
解决这个问题的一个思想是:应当尽可能使线程运行完毕,也就是说使run方法能正常退出,这样就不会出现锁没有释放的情况,从而也不会导致内存泄漏。
根据这个思想,我决定使用java的同步机制来实现这些功能,具体使用的是并非众所周知的wait、notify/notifyAll同步策略。
具体实现参见一下代码:
public
class
CustomThread
implements
Runnable
{
private boolean isSuspend;// 线程是否挂起标志
private boolean isStop;// 线程是否停止标志
private Thread innerThread;// 内部线程
/**
* 空构造函数
*/
public CustomThread()
{
isSuspend = false;
isStop = false;
}
/**
* 自实现start方法,该方法可以调用多次,而在Thread里的start方法只能调用一次
*/
public void start()
{
isSuspend = false;
isStop = false;
innerThread = new Thread(this);
innerThread.start();
}
/**
* 自实现suspend方法
*/
public void suspend()
{
isSuspend = true;
}
/**
* 自实现resume方法
*/
public void resume()
{
isSuspend = false;
synchronized (innerThread)
{
innerThread.notifyAll();
}
}
/**
* 自实现stop方法
*/
public void stop()
{
isStop = true;
if (isSuspend == true)
{
synchronized (innerThread)
{
innerThread.notifyAll();
}
}
}
/*
* (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
public void run()
{
// 线程运行前的准备工作--beforeRun
while (true)
{
if (isSuspend == true)
{
synchronized (innerThread)
{
if (isSuspend == true && isStop == false)
{
try
{
wait(0);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
if (isStop == true)
{
break;
}
//真正的运行代码--run
}
//线程运行完前的善后处理
}
}
{
private boolean isSuspend;// 线程是否挂起标志
private boolean isStop;// 线程是否停止标志
private Thread innerThread;// 内部线程
/**
* 空构造函数
*/
public CustomThread()
{
isSuspend = false;
isStop = false;
}
/**
* 自实现start方法,该方法可以调用多次,而在Thread里的start方法只能调用一次
*/
public void start()
{
isSuspend = false;
isStop = false;
innerThread = new Thread(this);
innerThread.start();
}
/**
* 自实现suspend方法
*/
public void suspend()
{
isSuspend = true;
}
/**
* 自实现resume方法
*/
public void resume()
{
isSuspend = false;
synchronized (innerThread)
{
innerThread.notifyAll();
}
}
/**
* 自实现stop方法
*/
public void stop()
{
isStop = true;
if (isSuspend == true)
{
synchronized (innerThread)
{
innerThread.notifyAll();
}
}
}
/*
* (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
public void run()
{
// 线程运行前的准备工作--beforeRun
while (true)
{
if (isSuspend == true)
{
synchronized (innerThread)
{
if (isSuspend == true && isStop == false)
{
try
{
wait(0);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
if (isStop == true)
{
break;
}
//真正的运行代码--run
}
//线程运行完前的善后处理
}
}
上面是简单的实现,还不能够重用,如果要实现重用,可以抽出接口来:
public
interface
CustomRunnable
{
/**
* 运行之前的初始化工作
*/
void beforeRun();
/**
* 运行代码
* @return -0表示要退出循环 其他:继续循环
*/
int run();
/**
* 运行结束后的善后处理
*/
void afterRun();
}
{
/**
* 运行之前的初始化工作
*/
void beforeRun();
/**
* 运行代码
* @return -0表示要退出循环 其他:继续循环
*/
int run();
/**
* 运行结束后的善后处理
*/
void afterRun();
}
原来的CustomThread重构为:
public
class
CustomThread
implements
Runnable
{
private boolean isSuspend;// 线程是否挂起标志
private boolean isStop;// 线程是否停止标志
private Thread innerThread;// 内部线程
private CustomRunnable runnableObject;//可运行对象
/**
* 空构造函数
* @param runnable -可运行对象
*/
public CustomThread(CustomRunnable runnable)
{
runnableObject = runnable;
isSuspend = false;
isStop = false;
}
/**
* 自实现start方法,该方法可以调用多次,而在Thread里的start方法只能调用一次
*/
public void start()
{
isSuspend = false;
isStop = false;
innerThread = new Thread(this);
innerThread.start();
}
/**
* 自实现suspend方法
*/
public void suspend()
{
isSuspend = true;
}
/**
* 自实现resume方法
*/
public void resume()
{
isSuspend = false;
synchronized (innerThread)
{
innerThread.notifyAll();
}
}
/**
* 自实现stop方法
*/
public void stop()
{
isStop = true;
if (isSuspend == true)
{
synchronized (innerThread)
{
innerThread.notifyAll();
}
}
}
/*
* (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
public void run()
{
// 线程运行前的准备工作
runnableObject.beforeRun();
while (true)
{
if (isSuspend == true)
{
synchronized (innerThread)
{
if (isSuspend == true && isStop == false)
{
try
{
wait(0);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
if (isStop == true)
{
break;
}
//真正的运行代码
int result = runnableObject.run();
if (0 == result)
{
break;
}
}
//线程运行完前的善后处理
runnableObject.afterRun();
}
}
{
private boolean isSuspend;// 线程是否挂起标志
private boolean isStop;// 线程是否停止标志
private Thread innerThread;// 内部线程
private CustomRunnable runnableObject;//可运行对象
/**
* 空构造函数
* @param runnable -可运行对象
*/
public CustomThread(CustomRunnable runnable)
{
runnableObject = runnable;
isSuspend = false;
isStop = false;
}
/**
* 自实现start方法,该方法可以调用多次,而在Thread里的start方法只能调用一次
*/
public void start()
{
isSuspend = false;
isStop = false;
innerThread = new Thread(this);
innerThread.start();
}
/**
* 自实现suspend方法
*/
public void suspend()
{
isSuspend = true;
}
/**
* 自实现resume方法
*/
public void resume()
{
isSuspend = false;
synchronized (innerThread)
{
innerThread.notifyAll();
}
}
/**
* 自实现stop方法
*/
public void stop()
{
isStop = true;
if (isSuspend == true)
{
synchronized (innerThread)
{
innerThread.notifyAll();
}
}
}
/*
* (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
public void run()
{
// 线程运行前的准备工作
runnableObject.beforeRun();
while (true)
{
if (isSuspend == true)
{
synchronized (innerThread)
{
if (isSuspend == true && isStop == false)
{
try
{
wait(0);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
if (isStop == true)
{
break;
}
//真正的运行代码
int result = runnableObject.run();
if (0 == result)
{
break;
}
}
//线程运行完前的善后处理
runnableObject.afterRun();
}
}
好了,所有工作都准备好了,下面只要实现接口CustomRunnable,然后创建这个对象并将之传给CustomThread的构造函数创建CustomThread对象,就可以放心使用start、suspend、resume、stop方法了