小弟最近在写一个网上考试系统作毕业设计,是cs结构的,在关闭服务器时遇见这样的问题:
启动服务器时,我在ExamServer(界面)上新建一个线程,在这个线程上new了一个ServerManager类,这个类负责和客户端交互信息,在这个类中建了如s,ss,dis,dos,con,stmt等资源,另外在ExamServer(界面)上有个按钮:关闭服务器,我想触发后通过ServerManager中的stop方法(一系列的.close()) 释放刚才那些资源,不知道该怎么办了,因为刚才那个线程找不到了,即使找到了 一个线程调用start()后,在run()方法退出前并发调用那方法将导致start()掷出一个java.lang.IllegalThreadStateException对象。
程序大概是这样的:
public class ExamServer
{
....
....
....
class ExamActionListener implements ActionListener
{
....
....
....
if(e.getActionCommand()== "启动服务器 ")
{
new Thread(new ManagerThread()).start();
}
if(e.getActionCommand()== "关闭服务器 ")
{
//这里该怎么写?
}
}
....
class ManagerThread implements Runnable //负责启动服务器的线程
{
public void run()
{
serverManager = new ServerManager(ExamServer.this);
serverManager.create();
}
}
}
public class ServerManager
{
public void create()
{
//这里创建了ss,s,dis,dos,con等资源
}
public void stop()
{
//这里释放了ss,s,dis,dos,con等资源
}
}
小弟弄了好长时间都解决不了,还望高手指教,谢谢!
另外一个问题:
另外,我想在client和server间传数组或对象,怎么传啊?我看到java.io.ObjectOutputStream.writeObject(java.lang.Object)
中:
将指定的对象写入 ObjectOutputStream。对象的类、类的签名,以及类及其所有超类型的非瞬态和非静态字段的值都将被写入。可以使用 writeObject 和 readObject 方法重写类的默认序列化。由此对象引用的对象是以可变迁的方式写入的,这样,可以通过ObjectInputStream 重新构造这些对象的完全等价的图形。
好多词不明白,不知道怎么用
非常感谢!!!
------解决方案--------------------
将指定的对象写入 ObjectOutputStream。对象的类、类的签名,以及类及其所有超类型的非瞬态和非静态字段的值都将被写入。可以使用 writeObject 和 readObject 方法重写类的默认序列化。由此对象引用的对象是以可变迁的方式写入的,这样,可以通过ObjectInputStream 重新构造这些对象的完全等价的图形。
这些是传的过程,你不用管这些,你只管调用函数就行了。
网络能传输什么?文本,二进制。就是能保存在磁盘里的。而对象在哪?对象在内存中。
所以传输过程就是先把对象保存成文本或二进制,然后传过去。接受端接受以后在恢复成内存中的对象。就是一个序列化反序列化的过程。
保存对象的过程:保存对象的类型,然后保存定义对象当前状态的数据。
读取对象的过程:读取对象类型,创建该类型的一个空白对象,在该空白对象中填充保存在文件中的数据。
我们希望磁盘上的对象布局和内存中的对象布局保持一致。在面向对象程序设计中这种情况为 "持续性 "(persistence).
上面是以前记的序列化的笔记。磁盘上的对象布局和内存中的对象布局是理解的关键。
------解决方案--------------------
1.关闭线程:Thread.currentThread().stop()/destroy();
2.首先你要明白,在网络上传输(tcp/ip)是不认对象的,只能认二进制的bits,也就是流格式。
所以用ObjectOutputStream.writeObject 转化成Stream传输,然后用ObjectinputStream.readObject()读取流进行还原。
------解决方案--------------------
你保证你写出的对象是可序列化的就可以了,也就是实现Serializable接口的类
你的C/S通过什么通信?Socket吗?
那你的服务器端就应该放在一个循环里才对,线程的run方法执行完,这个线程结束了
例如:
class ManagerThread implements Runnable //负责启动服务器的线程
{
boolean begin = true;
serverManager = new ServerManager(ExamServer.this);
serverManager.create();
public void run()
{
while(begin)
{
// 你的代码
}
}
public void stop()
{
// 你的代码
begin = flase;
}
}
参考下
------解决方案--------------------
重开线程,你的所有对象得重新初始化,这样不太好吧,你那个线程,run方法执行完,线程自动就消
亡了,垃圾机制自动回回收的,
public class ExamServer
{
....