多线程中buffer的大小的最优值

现在有两个线程,一个读线程,一个写线程,写线程向一个buffer里面写数据,读线程从buffer里面读数据,其中buffer被分成5个小块,每个小块是1KB,读每个小块的... 现在有两个线程,一个读线程,一个写线程,写线程向一个buffer里面写数据,读线程从buffer里面读数据,其中buffer被分成5个小块,每个小块是1KB,读每个小块的时候会加锁,写每个小块的时候也会加锁,每次读也只是读一块,每次写也只是写一块,但整个buffer没有加锁,当buffer有多少块时,整个buffer才不会溢出呢?我个人觉得这要看读线程和写线程的速度吧,但线程的速度是怎么控制的呢?
多谢两位的回答,但其实我想问的重点是“其中buffer被分成若干个小块(块数是由自己决定的),每个小块是1KB,读每个小块的时候会加锁,写每个小块的时候也会加锁,每次读也只是读一块,每次写也只是写一块,但整个buffer没有加锁,当buffer有多少块时,整个buffer才不会溢出呢?也就是说buffer的最优值要怎么计算呢?”Sorry,可能是我之前问的不够清楚
展开
 我来答
365297318xu
2011-01-28 · TA获得超过354个赞
知道小有建树答主
回答量:935
采纳率:0%
帮助的人:399万
展开全部
程序执行时间是和程序的周期有关的
线程是不能加快执行速度反而降低的
因为计算机在开启多个线程的同时需要对线程进行管理和切换

如果你非要加快执行速度
那么 不要使用 DoCalc(i)
在for语句中调用函数会每次都新建函数里面的变量
把DoCalc(i)的语句都直接写到for里,而变量写在for之外。
这样减少程序执行不必要的代码行,及时释放资源,减少对CPU时间的消耗

或者采用如下方法:
操作系统会为每个程序分配时间片
你可以打开任务管理器,查看->选择列->CPU时间 可以看到每个程序拥有的时间
同时这些时间又会更细的分配给线程

由此看来,你的程序拥有的时间是一定的
CPU只会分配这么多时间给你

如果你要通过操作系统来提高处理速度,那么,提高程序的优先级
因为程序拥有的时间片是间断的,如果提高优先级
那么他拥有的时间片可能会变成连续,这样,速度会显著提高

System.Diagnostics.Process p = ...;
p.PriorityClass = System.Diagnostics.ProcessPriorityClass.BelowNormal;
// 注意,这里是设置为低于标准

在C#里应该有直接提高自己进程优先级的 我以前做过
我这里使用的是windows 的API

---------------------------------------------
补充一点:
线程在有些时候可以提高减少程序执行的时间(不是CPU时间)
比如在等待某些资源的时候
我相信你肯定知道,线程之间资源是共享的

这样的话,我们对100个IP进行发送信息探测
如果顺序执行,那么CPU会执行如下顺序:
发送信息->等待(a)->接收回复->处理->发送信息...
注意,等待并不耗费CPU,我们需要等待100*a的时间

但是如果使用线程的话,100个线程同步进行:
发送信息->等待(a)->接收回复->处理
发送信息->等待(a)->接收回复->处理
发送信息->等待(a)->接收回复->处理
发送信息->等待(a)->接收回复->处理
....
这样等待时间就是 a
能减少程序执行时间,但是不减少CPU执行时间

-------------
但是由于你的程序不需要任何等待,这样,CPU一直是执行的
所以,程序执行时间基本等于CPU时间
cdunna
2011-01-29 · TA获得超过1676个赞
知道小有建树答主
回答量:1.9万
采纳率:0%
帮助的人:1594万
展开全部
首先说明,你的程序逻辑并没有问题,只是 System.out.println 放置的位置有些问题。
你可能对于下面的输出结果感到有些困惑:

Sender put : 1
Receiver get : 1
Sender put : 2
Sender put : 3
Receiver get : 2
Receiver get : 3
Receiver get : 4
Sender put : 4
Sender put : 5
Receiver get : 5

我起初也是,但是仔细琢磨了一下,发生这样的问题的原因如下:
首先要说明的是:哪个线程先获得 System.out 对象在打印字符串的时候就会先输出到控制台。
因为你的语句:
System.out.println("\t\t\tReceiver get : " + buffer.get()) ;
执行该语句会先执行:buffer.get(),然后再执行控制台输出。所以在 执行完 get() 中的唤醒语句后,还会有一个时间空隙来执行输出。
这就给 put 线程时间可以执行。
所以就有可能会输出上面的结果,我修改了一下 打印语句的位置,这次会严格按照你预想的进行输出:

public class MyBufferLock
{
private int value; //共享变量
private boolean isEmpty = true; //value是否为空的信号量

public synchronized void put(int i) //同步方法
{
// System.out.println("int put i=" + i );
while (!isEmpty) //当value不空时,等待
{
try
{
// System.out.println("putting...");
this.wait(); //使调用该方法的当前线程等待,即阻塞自己

}
catch(InterruptedException e) {}
}

System.out.println("Sender put : " + i );
value = i; //当value空时,value获得值
isEmpty = false; //设置value为不空状态
notify(); //唤醒其他等待线程
}

public synchronized int get() //同步方法
{
// System.out.println("\t\t\tint get " );
while (isEmpty) //当value空时,等待
{
try
{
// System.out.println("\t\t\tgetting...");
this.wait();
}
catch(InterruptedException e) {}
}

isEmpty = true; //设置value为空状态,并返回值
notify();
System.out.println("\t\t\tReceiver get : " +value ) ;
return value;
}
}

class MySender extends Thread //发送线程类
{
private MyBufferLock buffer;

public MySender(MyBufferLock buffer)
{
this.buffer = buffer;
}

public void run( )
{
for (int i=1;i<6;i++)
{
buffer.put( i );
// System.out.println("Sender put : " + i );
}
}
}

class MyReceiver extends Thread //接收线程类
{
private MyBufferLock buffer;

public MyReceiver(MyBufferLock buffer)
{
this.buffer = buffer ;
}

public void run()
{
for (int i=1; i<6;i++) {
buffer.get();
// System.out.println("\t\t\tReceiver get : " + buffer.get()) ;
}
}

public static void main (String args[])
{
MyBufferLock buffer = new MyBufferLock();
(new MySender(buffer)).start();
(new MyReceiver(buffer)).start();
}

}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
knifsleep
2011-02-01 · TA获得超过702个赞
知道小有建树答主
回答量:1219
采纳率:51%
帮助的人:225万
展开全部
你说的‘溢出’指什么?
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式