在一个循环中产生多个线程实例调用,程序如下:
public class testrun
{
public static void main(String[] args)
{
int i = 1 ;
for (i=1;i<100 ;i++ )
{
new test(i).start();
}
}}
class test extends Thread
{
private int iNum = 0;
boolean stoped = false;
public test(int num)
{
this.iNum = num ;
}
public void run()
{
synchronized (this) {
while (!stoped)
{
try
{
this.sleep(30);
}catch(Exception e) {
//
}
System.out.println("正在运行第" + iNum + "个线程!");
}
}
}
public void stoped()
{
this.stoped = true;
}
}运行结果,多个线程无限的在执行,而且顺序并不是从1到100,而是乱的,如果我采用stoped()方法来停止,我在main方法中如何调用????如何才能让线程一个接着一个的去执行?如何控制?其次,如果我的主程序中的循环量很大,比如说1亿次,甚至是100亿次,那将会产生100亿个线程实例,会不会有问题?应该如何处理?
public class testrun
{
public static void main(String[] args)
{
int i = 1 ;
for (i=1;i<100 ;i++ )
{
new test(i).start();
}
}}
class test extends Thread
{
private int iNum = 0;
boolean stoped = false;
public test(int num)
{
this.iNum = num ;
}
public void run()
{
synchronized (this) {
while (!stoped)
{
try
{
this.sleep(30);
}catch(Exception e) {
//
}
System.out.println("正在运行第" + iNum + "个线程!");
}
}
}
public void stoped()
{
this.stoped = true;
}
}运行结果,多个线程无限的在执行,而且顺序并不是从1到100,而是乱的,如果我采用stoped()方法来停止,我在main方法中如何调用????如何才能让线程一个接着一个的去执行?如何控制?其次,如果我的主程序中的循环量很大,比如说1亿次,甚至是100亿次,那将会产生100亿个线程实例,会不会有问题?应该如何处理?
//循环量很大理论上没问题,不过i要定义为具有更大范围的如double等
test t = new test(i);
t.start();
try {
Thread.sleep(100);//线程间启动有一定的延迟就ok了
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t.stoped();//控制线程的结束
}
import java.util.*;
public class testrun
{
public static void main(String[] args)throws Exception{
for (int i=1;i<100 ;i++ ){
new test(i).join();
}
}}
class test extends Thread{
private int iNum = 0;
public test(int num){
this.iNum = num ;
this.start();
}
public void run(){
synchronized (this){
System.out.println("正在运行第" + iNum + "个线程!");
}
}
}sleep()也不是什么控制线程执行的办法。它只是暂停线程。唯一能保证的事情是,它会休眠至少100毫秒,但是它恢复运行所花的时间可能更长,因为在休眠结束之后,线程调度机制还要花时间来接管。
是不是在一个线程执行完以后才开始执行别的线程?
// Run the Thread
public void run()
{
synchronized(this) {
//System.out.println(url);
CheckUrl(url);
}
}
public void CheckUrl(String url)
{
//Util.ShowMessage("Start to Check the " + url);
if(new Http().Get(url)) {
Util.ShowMessage("OK");
} else {
Util.ShowMessage("Failure");
} }
在CheckUrl方法中加入了检测web文件是否存在的判断,比如url="http://www.163.com/index.asp"
如果存在就会显示"OK"
但我发现这样在执行CheckUrl方法的时候,比原来的速度要慢很多,原来很快,但线程无法顺序执行,也不能产生正确的线程数量;按照interhanchi(闭关修练中!) 老兄的方法修改后,可以正确执行了,也就是用了join()方法,但速度却慢了,如何处理和优化,还有就是,假如有100亿次循环,产生100亿个线程,会不会出现问题,如何释放以前执行完了的线程??????
join()方法,只不过要求本线程结束后才调度与之关联的线程,线程越多运行速度越慢;
你的问题本身就是矛盾的:既要顺序又要并发,不可能的
我测试过,如果采用start()方法调用,其产生的线程是乱的,而且一直不结束????为什么,应该如何处理?
所以不要用这么方法来处理这种事情。你可以用开辟一个队列来缓冲数据,
然后用很多线程来轮询这个队列。比如 10000个,采用同步的方式读取队列中的元素,。
当然你也可以根据实际的队列大小动态的增加或者减少队列个数。线程的模型如下。where(!stopFlag)
{
objData =queue.同步读并移除队列头元素方法();
dealData();
}其中 queue对象 采用同步方法进行增加读取。
模型类似一个生产者,多个消费者。
Start to Check url www.163.com/xxx.asp
.........................
Connection timed out: connect
No buffer space available (maximum connections reached?): JVM_Bind
No buffer space available (maximum connections reached?): JVM_Bind
No buffer space available (maximum connections reached?): JVM_Bind
No buffer space available (maximum connections reached?): JVM_Bind
Connection timed out: connect
Connection timed out: connect
Connection timed out: connect
Connection timed out: connect
Connection timed out: connect
No buffer space available (maximum connections reached?): JVM_Bind
No buffer space available (maximum connections reached?): JVM_Bind
Connection timed out: connect
Connection timed out: connect
Connection timed out: connect
Connection timed out: connect
No buffer space available (maximum connections reached?): JVM_Bind
Connection timed out: connect
No buffer space available (maximum connections reached?): JVM_Bind
No buffer space available (maximum connections reached?): JVM_Bind
No buffer space available (maximum connections reached?): JVM_Bind
No buffer space available (maximum connections reached?): JVM_Bind
No buffer space available (maximum connections reached?): JVM_Bind
No buffer space available (maximum connections reached?): JVM_Bind
..............................
是不是并发的线程,在分别处理socket通信问题上出现了什么问题?????如何处理???其中程序如下:
public boolean CheckUrl(String url)
{
try
{
if(CheckHttp(url))
{
OpenServer(target.getHost(),target.getPort());
String cmd = "Get " + getURLFormat(target) + " HTTP/1.0\r\n"
+ getBaseHeads() + "\r\n";
sendMessage(cmd);
receiveMessage();
if (responseCode!=200)
{
return false;
}
}
else
{
return false;
}
}
catch(Exception e)
{
Util.ShowMessage(e.getMessage());
return false;
}
return true;
}/**
* CheckHttp方法检测当前请求的URL是否是有效的HTTP协议.
*/
protected boolean CheckHttp(String httpUrl)
{
try
{
URL target = new URL(httpUrl);
if(target==null || !target.getProtocol().toLowerCase().equals("http"))
{
Util.ShowMessage(httpUrl + "=========错误。原因是因为目标地址不是有效的HTTP协议==========");
return false;
}
this.target = target;
}
catch(MalformedURLException m)
{
Util.ShowMessage(m.getMessage());
return false;
}
return true;
}
/**
* 与Web服务器连接。若找不到Web服务器,InetAddress会引发UnknownHostException
* 异常。若Socket连接失败,会引发IOException异常。
*/
protected void OpenServer(String host,int port) throws
UnknownHostException,IOException
{
header.clear();
responseCode = -1;
responseMsg = "";
try
{
if(client != null) {
CloseServer();
}
if(byteStream != null) {
byteStream.close();
byteStream = null;
}
InetAddress addr;
try
{
addr = InetAddress.getByName(host);
}
catch(UnknownHostException u)
{
throw u;
}
client = new Socket(addr,(port==-1?80:port));
sender = new BufferedOutputStream(client.getOutputStream());
receiver = new BufferedInputStream(client.getInputStream());
}
catch(IOException e)
{
throw e;
}
}
protected String getURLFormat(URL target)
{
String spec = "http://"+target.getHost();
if(target.getPort()!=-1)
spec+=":"+target.getPort();
return spec+=target.getFile();
} protected String getBaseHeads() {
String inf = "User-Agent: myself Http/1.0\r\n"+
"Accept: www/source; text/html; image/gif;application/data; */*\r\n";
return inf;
}
/* 向Web服务器传送数据 */
protected void sendMessage(String data) throws IOException{
sender.write(data.getBytes(),0,data.length());
sender.flush();
}
/* 接收来自Web服务器的数据 */
protected void receiveMessage() throws IOException
{
byte data[] = new byte[1024];
int count = 0;
int word = -1;
// 解析第一行 while ((word = receiver.read()) != -1) {
if (word == '\r' || word == '\n') {
word = receiver.read();
if (word == '\n') word = receiver.read();
break;
}
if (count == data.length) data = addCapacity(data);
data[count++] = (byte) word;
}
String message = new String(data, 0, count);
int = message.indexOf(32);
serverVersion = message.substring(0, );
while (>responseCode)
{
responseCode = Integer.parseInt(message.substring( + 1, += 4));
}
responseMsg = message.substring(, message.length()).trim();// 应答状态码和处理请读者添加
switch (responseCode) {
case 400:
throw new IOException("错误请求");
case 404:
throw new FileNotFoundException(getURLFormat(target));
case 503:
throw new IOException("服务器不可用");
case 501:
throw new IOException("文件不能执行,或无法实现!");
} if (word == -1)throw new ProtocolException("信息接收异常终止");
return ;
}
private byte[] addCapacity(byte rece[])
{
byte temp[] = new byte[rece.length + 1024];
System.arraycopy(rece, 0, temp, 0, rece.length);
return temp;
}
还有CheckUrl方法中执行了socket的程序,所耗费的时间相对较长,如何控制才好,谢谢了!
http://blog.csdn.net/cozmic/archive/2005/08/16/455584.aspx
这些线程的功能很简单是 取 队列里的头元素并进行处理的。
而且是不断的运行的。
你估算一下 处理一个数据需要多长时间比如是 t_deal。
在一段时间内最多有多少 数据到达。比如 m个
你需要的 达到的响应时间是 t_want.(t_want >= t_deal)
假设你的机器比较牛x,刨除那些不良的小节的影响因素。
你需要开辟的线程数 n 大致 m/(t_want/t_deal)<= n <= m
package xxx.xxx.xxx
import java.util.logging.*;
import java.util.*;
import ssts.util.*;
/**
* SyStaticSendQueue类构造一个用于多线程同步与互斥访问的静态队列,提供队列数据结构的相应访问.
*/
public class SyStaticSendQueue { private static List queue = Collections.synchronizedList(new LinkedList());
private static Logger log = QueueLog.getLogger();/**
* 提供一个具有同步与互斥操作的进队操作.<br>
* 例如:String content = new String("0"+ id + data);<br>
* String len = String.valueOf(content.length());<br>
* content = len+content;<br>
* SyStaticQueue.enQueue( content );
* @param obj 进入队列的对象(例如:数据报文内容)
* @return 无返回
* @see ssts.asycom.AsyCom
*/
public static void enQueue( Object obj )
{
synchronized ( queue )
{
while( queue.size() >= 10240 )
{
log.finer("queue is full ! " + queue.size());
try{
queue.wait();
}catch(Exception e)
{
e.printStackTrace();
}
}
queue.add(obj);
log.finer("queue size is : "+queue.size());
queue.notifyAll();
}
}/**
* 提供一个具有同步与互斥操作的出队操作.
* @param 无
* @return 队列中的对象
* @see ssts.asycom.AsyCom
*/ public static Object dlQueue()
{
Object obj = null;
synchronized ( queue )
{
while( queue.isEmpty() )
{
try{
queue.wait();
}catch(Exception e)
{
e.printStackTrace();
}
}
obj = queue.remove( 0 );
log.finer("queue size is : "+queue.size());
queue.notifyAll();
}
return obj;
}
/**
* 提供一个具有同步与互斥操作的取对列头元素的操作.
* @param 无
* @return 排在队列中的第一个对象
* @see ssts.asycom.AsyCom
*/ public static Object getHead()
{
Object obj = null;
synchronized ( queue )
{
while( queue.isEmpty())
{
try{
queue.wait();
}catch(Exception e)
{
e.printStackTrace();
}
}
obj = queue.get( 0 );
}
return obj;
}
/**
* 提供一个具有同步与互斥操作的判空操作.
* @param 无
* @return true 队列为空 false 队列非空
* @see ssts.asycom.AsyCom
*/
public static boolean empty()
{
boolean flag = false;
synchronized ( queue )
{
if( queue.isEmpty())
{
flag = true;
}
else
{
flag = false;
}
}
return flag;
}/**
* 提供一个具有同步与互斥操作的取队列尺寸操作.
* @param 无
* @return 队列尺寸值
* @see ssts.asycom.AsyCom
*/
public static int getSize()
{
int size = 0;
synchronized ( queue )
{
size = queue.size();
}
return size;
}
}
class dealData extends Thread
{
private boolean runFlag = false;
void run()
{
where(runFlag)
{
objData = SyStaticSendQueue.dlQueue()
//在这里处理这些数据
}
}
void setRunFlag(boolean xbFlag)
{
runFlag = xbFlag;
}
}// 数据生产类 示意 所有需要往这个队列里面增加需要处理元素的线程都采用下面的方式增加。class appendData()
{
public static void main(String[] args)
{
SyStaticSendQueue.enQueue(objData);
}
}
// 主控调度class main_do()
{
public static void main(String[] args)
{
dealData workThread[xxx] ;
for (int i = 0 ; i < xxx ; i ++ )
{
workThread[i] = new dealData();
workThread[i].setRunFlag(true);
workThread[i].start();
} // 需要关闭的时候 for (int i = 0 ; i < xxx ; i ++ )
{
workThread[i].setRunFlag(false);
}
} }
vector v = new vector();
for (int i = 0; i <num ; i++)
{
v.addElement(i);
}如果其中的Num值非常大,比如说10亿(1000000000)时,程序运行中就会出现:Exception in thread "main" java.lang.OutOfMemoryError的错误,请问如何处理才不会出现这样?vector支持的最大值时多少?
实际上系统还把最高位当作符号位了 有效为只有 31位 ,再看着两个函数。
public synchronized void addElement(Object obj) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = obj;
} private void ensureCapacityHelper(int minCapacity) {
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) { //如果最小的需要存储的个数大于 已有的空间。
Object oldData[] = elementData;
//如果指定了增长个数,则按照 旧的空间大小加上增长的空间大小 来确定新空间大小。
//否则按照两倍的旧空间大小来确定新空间大小。
int newCapacity = (capacityIncrement > 0) ?
(oldCapacity + capacityIncrement) : (oldCapacity * 2); //如果确定的新空间大小仍然小于最小需要存储的空间大小。则新空间大小更改为最小需要存储空间的大小
if (newCapacity < minCapacity) {
newCapacity = minCapacity;
}
elementData = new Object[newCapacity];
//拷贝旧的空间内容到新的空间大小里面来。
System.arraycopy(oldData, 0, elementData, 0, elementCount);
}
}//在这种情况下outofmemory很大部分是因为 虚拟机分配的内存和堆栈空间太小。
//在研究一下源码,如果预计在一段时间内会很频繁很大量的使用vector来存放东西,那么
//最简单的策略是一次性给他分配齐了。当然也可以根据需要来定制内存分配策略。
//下面是例子,运行通过的
// 关于虚拟机的选项 具体参考 (随便搜的)
// http://www.apple.com.cn/developer/Documentation/Java141Development/VM_Options/chapter_11_section_1.htmlimport java.util.*;
class TestVector
{
public static void main(String[] args)
{
// Integer.MAX_VALUE == 2147483647 Vector aa = new Vector(Integer.MAX_VALUE,0); System.out.println("Hello World!");
}
}java -Xms256m -Xmx256m TestDown
我在我的机器上测试了您的代码,如下:
import java.util.*;
public class test
{
public static void main(String args[])
{
int MAX_VALUE = 2147483647;
Vector v = new Vector(MAX_VALUE,0);
System.out.println("OK");
}
}D:\java>java -Xms256m -Xmx256m test
Exception in thread "main" java.lang.OutOfMemoryError为什么我的机器上还是不行呢?我把256M,换成512M也不行,我的机器是P4 2.8G+1G(Memory),是不是还有什么地方我写的不对 ????
import java.util.*;
public class test
{
public static void main(String args[])
{
Vector v = new Vector(Integer.MAX_VALUE,0);
System.out.println("OK");
}
}
D:\java>javac test.javaD:\java>java -Xms256m -Xmx256m test
Exception in thread "main" java.lang.OutOfMemoryErrorD:\java>不知什么原因???
开发环境: window 2000 server p42.5 512m
编辑环境: editplus
编译环境: j2sdk1.4.1_02你换一个机器试一下我运行通过了之后才发上去的。
在不加上 -Xms256m -Xmx256m
会出现 OutOfMemoryError
加上之后就没有了,
我怀疑是环境问题。
1、从字符集中产生指定位数的所有排列和组合
2、将产生的每个组合字符串与http服务器上的文件进行比较,判断是否存在
3、成功时将当前字符串存入文本第一步已经完成(以前采用生成后的字符组合存入文本文件,后来结果太大,放弃存入文件);
第二步中的检测功能已经完成,由于第一步中没有采用存入文本文件,我设想在每产生一个字符组合后,就将该字符组合进行第二步的处理,当第二步完成后,重复第一步产生下一个........程序描述:
第一步(循环产生所有的排列组合)
{
if (产生单个排列组合 )
{
第二步检测http文件;
if (成功) 第三步;
}
}
编辑环境: editplus
编译环境: j2sdk1.4.1_02
vector v = new vector(Integer.MAX_VALUE,0);
这种方式没能通过,不知到象上面我所描述的功能,是不是应该如此使用(其中产生了多线程的循环问题):
程序描述:
第一步(循环产生所有的排列组合)
{
if (产生单个排列组合 )
{
*****多线程执行(第二步检测http文件)*****;
if (成功) 第三步;
}
}
但是我确实是已经运行成功之后才发上去的,代码很短,
我没有记错。后来我该了一下代码。import java.util.*;
class TestVector
{
public static void main(String[] args)
{
// Integer.MAX_VALUE == 2147483647 int iSize = 100*1024*1024; //100m Vector aa = new Vector(iSize,0); System.out.println("Hello World!");
}
}当 iSize == 100M 时在
java -Xms512m -Xmx512m TestVector
下能运行
但在 java -Xms256m -Xmx256m TestVector 就不行了(也成功过1次)。
当 iSize == 300M 时
在 java -Xms512m -Xmx512m TestVector
我只成功过2次,其他次都不行。很奇怪。
我的机器内存才 512M 不能在增加 -Xmx 了。 你跟boss申请内存吧,呵呵 然后再增大
1. 产生排列组合串
2. 根据提供的串排列组合匹配数据
3. 符合匹配数据的内容做特殊处理算法描述:
1. 主线程做字符串串排列组合, 得到串后将其写入一个读取队列A(需要限定队列的总长度)
2. 建立线程池(数量可设定), 线程池中线程扫描并读取队列A, 并做数据匹配动作
3. 如果匹配成功, 将数据写入输出队列B. 线程池做下一次匹配处理
4. 由特殊处理线程(或线程组)扫描输出队列B, 做相应的特殊处理
原模型如下:
输入接受处理===> 输入缓冲 ==〉主处理 ==>输出缓冲 ==>输出处理
其中 输入接受处理,主处理 ,输出处理 都是并发的且缓冲区两侧都遵循
生产者消费者模型。当然在实现上不是太严格。其实也不一定要输出缓冲。就看那个部分性能评价的权比较大。
楼主为什么要让这个队列超出这个长度呢?
输入队列不是有长度吗?为什么不用它来做限制?
如果缓冲满的话,就会暂停输入的。
缓冲空的话也会暂停读取的。
我在使用循环调用enQueue()方法,当size()>100K时就等待,但屏幕显示waiting..........,后就一直不动了,那这样岂不是无法执行下去,或者速度很慢了??????????????
public static void enQueue( Object obj )
{
synchronized ( queue )
{
if( queue.size() >= 100 * 1024 )
{
System.out.print("Waiting..........");
try{
queue.wait();
}catch(Exception e)
{
e.printStackTrace();
}
}
queue.add(obj);
queue.notifyAll();
}
}
等待的目的就是要让处理1缓一下同步一下。