-
无法向ArrayList添加对象3
我用一个单例的管理类管理很多个list,现在我的其他的模块调用这个管理类并向它的一个ArrayList里面添加一个对象,但是这个ArrayList一直为null,另外说明这个ArrayList是放在一个线程里面反复循环的,因为我要通过里面的对象用socket向各个地方发包。另求socket接收和分发包的示例(自己作为一个流的管理者,下面的分支都向自己拉流,管理者根据请求的地址和端口发包)
代码如下:public class InviteStreamWorker extends Thread { public static List<StreamInviter> inviters = new ArrayList<StreamInviter>(); public void addInviter(StreamInviter inviter) { if (!checkExistInviter(inviter)) { inviters.add(inviter); } } @Override public void run() { HsSipUtil.info("method", "InviteStreamWorker.run()"); if (isStream) { byte[] buf = new byte[1024]; DatagramPacket packet = new DatagramPacket(buf, buf.length); DatagramPacket packetToSend; try { socket.receive(packet); packetToSend = new DatagramPacket(packet.getData(), packet.getData().length); if (inviters.size() > 0) { for (StreamInviter inviter : inviters) { HsSipUtil.info("address", inviter.getAddress()); HsSipUtil.info("port", inviter.getPort()); packetToSend.setAddress(InetAddress.getByName(inviter .getAddress())); packetToSend .setPort(Integer.valueOf(inviter.getPort())); socket.send(packetToSend); } } else { System.out.println("no inviter in list now"); } } catch (IOException e) { e.printStackTrace(); } } } }
问题补充:kidding87 写道if (isStream)
这个不知道你怎么判断的
而且你这个run很容易就run完了。。。
isStream这个可以不用考虑,后面已经撤销了这个判断了,现在可以加入对象了,但是packetToSend没发送出去吧,另外一台机器没接收到。
其实我是想把自己作为一个包的分发器,我本机上开放一个端口专门来接收数据,然后根据list里面的对象获取目标地址和端口向它们发送DatagramPacket,开线程的原因是不能阻塞程序,因为调用处理端口的程序还要执行其他的后续命令。我是想通过这个list的对象的有无控制这个流
问题补充:第一次写socket方面的东西不是很清楚,或许我socket的处理上本来就有问题,欢迎指出
问题补充:kidding87 写道用while(inviters.size()!=0){
//todo
//interval为循环的时间间隔
sleep(interval)
}
当然你要保证你的inviters插入和拿到数据都是正常的
虚拟机那边开放的UDP端口和我list里面的对象取得的IP和端口是相同的。
现在我有2个疑问
1.就是ArrayList能不能同步,因为我有可能后期加入新的inviter,那时它还会在循环一次吗?(我另外一个控制流集合的map用的是ConcurrentHashMap可以更新的)。
2.我的socket是UDP传输,那么我这个线程的结束是以socket收不到包了为生命周期还是说run方法结束了就结束,关键是UDP的包应该是不连续的吧,是收一个包run一次?
问题补充:aronlulu 写道想法没问题,实现的有些问题。
首先你触发循环list的条件应该是socket接收到包就触发,这个可以这么做:
写个static的ArrayBlockingQueue阻塞队列 ,socket接收到了就放到这个队列里。
run这个函数死循环做这个事情:
while(isRuning){
获取队列里的包,没有的话队列会阻塞等待,见ArrayBlockingQueue API take()
获取到包的话,遍历arraylist,发送这个包
}
另外既然你这个inviters 是多线程操作的,就用CopyOnWriteArrayList,即arraylist的多线程版本。
其实就是个生产者消费者模式,只不过生产者一个socket,消费者是多个socket。
谢谢你的回复,问题在一步一步解决中,用了死循环可以一直发包收包了(代码贴在问题补充里面),CopyOnWriteArrayList暂时没用到,ArrayList暂时满足现在的需求,先把整个流程跑通了在回头搞最优的。现在有个新的问题:
我现在是收到一个包就开始循环,我担心的是我的循环花的时间比收一个包多太多导致循环期间有很多包漏掉(我在控制台看到收包的频率很高的,一秒钟有十几个吧,当然包括循环的时间一起),因为现在只有一个inviter所以不觉得有什么,但是当inviter有几百,几千,甚至几万的时候问题就严重了,拉的是实时视频流,画面断断续续可不好,各位有没有比较好的解决方案,难道我要把包都存起来在另外一个地方挨个发?求解!另外注明一下:设计虽然都是我做的,但是本人代码能力稍差,不免走了一些弯路,希望前辈看到给我指出来,免得后期难做
问题补充:修改后的代码,可以实现一直向inviter发送UDP包,新问题:
我从其他地方拉流到我本机的时候是一百多K每秒,但是我发给别人的时候,流量显示都是兆级以上的秒流量,是我的packetToSend没有处理好还是本来就这样,求解。
代码如下@Override public void run() { HsSipUtil.info("method", "InviteStreamWorker.run()"); byte[] buf = new byte[1024]; DatagramPacket packet = new DatagramPacket(buf, buf.length); try { do { socket.receive(packet); for (StreamInviter inviter : getInviters()) { DatagramPacket packetToSend = new DatagramPacket( packet.getData(), packet.getData().length, InetAddress.getByName(inviter.getAddress()), Integer.valueOf(inviter.getPort())); socket.send(packetToSend); } System.out.println(new Date()); } while (inviters.size() > 0); } catch (IOException e) { e.printStackTrace(); } }
2012年3月19日 14:11
5个答案 按时间排序 按投票排序
-
采纳的答案
socket.send(packetToSend);
只有这里发送成功了,下个发送才会开始,也算是阻塞式发送这里我觉得可以
new Runnable(){}.start();
推荐一篇帖子你看看
http://www.iteye.com/topic/834447
使用nio来处理2012年3月20日 10:56
-
想法没问题,实现的有些问题。
首先你触发循环list的条件应该是socket接收到包就触发,这个可以这么做:
写个static的ArrayBlockingQueue阻塞队列 ,socket接收到了就放到这个队列里。
run这个函数死循环做这个事情:
while(isRuning){
获取队列里的包,没有的话队列会阻塞等待,见ArrayBlockingQueue API take()
获取到包的话,遍历arraylist,发送这个包
}
另外既然你这个inviters 是多线程操作的,就用CopyOnWriteArrayList,即arraylist的多线程版本。
其实就是个生产者消费者模式,只不过生产者一个socket,消费者是多个socket。2012年3月19日 17:23
-
对啊,你这个线程直接就跑玩了,什么都没做,就要让它一直跑着
还有你这个应该算作一个操作栈,建议自己继承个linkedlist,里面定义个
private volatile boolean hasNewCome;
在add的时候,去改变它的值,或者直接记录新加了什么东西
在run的时候一直去判断有没有新加的数据就可以了
当然我也就提供了一个思路2012年3月19日 15:38
-
用while(inviters.size()!=0){
//todo
//interval为循环的时间间隔
sleep(interval)
}
当然你要保证你的inviters插入和拿到数据都是正常的2012年3月19日 15:21
相关推荐
使用Add方法向ArrayList中添加元素。Add方法返回新添加元素的索引,这在某些情况下可能很有用。 ```csharp myList.Add("First Item"); myList.Add(123); ``` 4. 访问元素 通过索引来访问ArrayList中的元素,索引从...
1. **Add()**: 将指定的对象添加到`ArrayList`的末尾。 2. **AddRange()**: 将集合中的元素添加到`ArrayList`的末尾。 3. **Insert()**: 在`ArrayList`的指定位置插入一个新对象。 4. **InsertRange()**: 在`...
在这个主题中,我们将深入探讨如何在JNI中操作ArrayList对象并添加一个int类型的数据。 首先,我们需要理解ArrayList在Java中的本质。ArrayList是Java集合框架中的一个重要类,它实现了List接口,用于存储可变大小...
- 如果ArrayList包含自定义类型对象,记得覆盖ToString()方法,以确保在添加到ListBox时显示有意义的信息。 - 如果ListBox需要支持多选,需设置SelectionMode属性为MultiSimple或MultiExtended。 5. 优化与改进:...
1. 创建ArrayList并添加对象。 2. 将ArrayList设置为DataGrid的DataSource。 3. 指定DataGrid的列,映射ArrayList中对象的属性。 4. 在窗体中显示DataGrid。 尽管ArrayList在现代C#编程中逐渐被泛型集合取代,但...
在Java编程语言中,ArrayList是集合框架的一部分,属于List接口的实现类,它是一个动态数组,可以存储可变数量的对象。当我们说“arraylist对象中的某个值排序”时,这通常指的是对ArrayList中的元素,而不是...
// 添加学生对象到列表... // 首先按学号排序 Collections.sort(students, new StuNoCompared()); System.out.println("按学号排序:"); // 输出排序后的学生列表... // 然后按姓名排序 Collections.sort...
ArrayList是一个基于对象数组的动态大小的列表,而DataTable则是一个内存中的表格数据结构,通常用于存储和操作关系型数据。将ArrayList转换为DataTable是为了更好地利用DataTable的数据处理功能,例如查询、排序和...
- `Add` 方法用于将指定的对象添加到 `ArrayList` 的末尾。 - 此方法可以接受一个对象作为参数,并将其添加到列表的最后位置。 **示例代码**: ```csharp ArrayList arrlist = new ArrayList(); arrlist.Add("第一...
然后,我们可以创建一个ArrayList实例,并向其中添加`Employee`对象: ```csharp ArrayList employees = new ArrayList(); employees.Add(new Employee { Name = "张三", Age = 25, Position = "程序员" }); ...
假设我们有一个User类,包含如ID、姓名、年龄等属性,我们可以创建User对象并将其添加到ArrayList中。例如: ```java public class User { private int id; private String name; private int age; // 构造器...
在这个练习中,我们将创建一个ArrayList实例,向其中添加各种类型的对象,然后执行常见的操作,如遍历、查找、插入和删除元素。以下是一些可能的操作步骤: 1. 创建ArrayList实例: ```csharp ArrayList list = new...
例如,`myArrayList.Add(someObject)` 将对象someObject添加到ArrayList的末尾。 - `Insert`: 插入方法允许在指定索引处插入一个元素。例如,`myArrayList.Insert(index, someObject)` 在索引为index的位置插入...
在添加对象时,我们需要判断数组是否需要扩容。如果数组已经满了,我们需要创建一个临时数组temp,长度比原数组长,然后将原数组中的元素复制到临时数组中,最后将临时数组赋值给原数组。代码如下: ```java public ...
- `Add(object item)`: 向ArrayList末尾添加一个元素。 - `Insert(int index, object item)`: 在指定索引处插入一个元素。 - `Remove(object item)`: 删除第一个匹配给定值的元素。 - `RemoveAt(int index)`: ...
- `Add`和`AddRange`:分别向`ArrayList`的末尾添加一个元素或一系列元素。 - `Remove`、`RemoveAt`、`RemoveRange`:分别移除单个元素、指定索引位置的元素或指定范围内的元素。 - `Insert`和`InsertRange`:...
通常可以通过在访问`ArrayList`之前对`ArrayList`对象加锁来实现。 #### 总结 `ArrayList`是一种高效、灵活的动态数组实现,非常适合用于需要频繁添加和删除元素的场景。通过理解其内部实现机制,开发者可以更好地...
ArrayList以对象数组的形式存储数据,提供了动态增长的能力,便于增删改查操作。在处理大量数据时,排序是常见的需求,本篇文章将深入探讨ArrayList的排序方法。 首先,ArrayList本身并不提供直接的排序功能,但...
- `ArrayList` 中的元素默认为 `object` 类型,因此如果添加的是特定类型的元素(如 `int`),在使用时需要进行类型转换。 - `ArrayList` 可以动态地增加或减少元素数量。 #### 三、C# List<T> 类的用法及特点 **...