Java多线程小结–最近Coding的一点心得

  最近在写一个利用Java多线程的操作系统的课程设计,所以自然就开始认真学习了一下java有关多线程的一段知识,发现java对多线程的支持非常的好,一个锁机制可以解决大部分的问题。

  我的第一个小实验性的东西是两个buffer,3中角色——producer,consumer,mover。其中我感觉producer和mover是最好实现的,只要在buffer的定义中定义了相关的put,get同步操作即可,关键是mover。通过分析可以知道,mover必须同时持有两个两个buffer的锁才能进行move的操作,开始的是就想到了这里。做了一个简单的示例,发现不对,总是会假死。事后才知道这是发生了死锁。开始的时候百思不得其解。于是去吃晚饭,过了一会儿,突然有了想法——两个mover实例并发导致了死锁。

  发生死锁的原因:mover1取得了buf1,buf2的锁,然后发现buf2满,于是释放buf2的锁,notify了consumer,consumer于是开始cost,cost之后,notify,结果把锁给了另一个Mover,于是就这样了——mover1有buf1的锁,想要buf2,mover2有buf2的锁,想要buf1。死锁形成。我给出的解决方法比较粗糙,就是在mover类中设置一个静态的Object作为mover所有实例的锁,mover首先要取得该锁,然后才可以取得buf1,buf2的锁,简单说就是叫mover串行。

  结果很成功。

  第二个实验:多个factory,多个store,都是buffer,然后还是3类——producer,mover,consumer。这回的难点是选择策略——由于每次producer不一定非要在同样的buffer间搬运,因此就存在每次running时候的选择问题,如何选更加智能,尤其对于Mover,如何选择才能使之比较高效而且没有死锁。

  经过考虑和实验,我的解决方法是利用Java自带的随机函数,new Random().nextInt(bufs.size())来随机选择

  这里有Java API相关的解释:

  nextInt

  public int nextInt(int n)

  返回一个伪随机数,它是取自此随机数生成器序列的、在 0(包括)和指定值(不包括)之间均匀分布的 int 值。nextInt 的常规协定是,伪随机地生成并返回指定范围中的一个 int 值。所有可能的 n 个 int 值的生成概率(大致)相同。Random 类按如下方式实现 nextInt(int n) 方法:

  public int nextInt(int n) { if (n<=0) throw new IllegalArgumentException(“n must be positive”); if ((n & -n) == n) // i.e., n is a power of 2 return (int)((n * (long)next(31)) >> 31); int bits, val; do { bits = next(31); val = bits % n; } while(bits – val + (n-1) < 0); return val; }

  前面的描述中使用了不确定的词“大致”,因为 next 方法只是一个大致上独自选择位的无偏源。如果它是一个随机选择位的最佳源,那么给出的算法应该从规定范围完全一致地选择 int 值。

  该算法稍微有些复杂。它拒绝那些会导致不均匀分布的值(由于 2^31 无法被 n 整除)。某个值被拒绝的概率取决于 n。最坏的情况是 n=2^30+1,拒绝的概率是 1/2,循环终止前的预计迭代次数是 2。

  该算法特别对待 n 是 2 的次幂的情况:它从底层伪随机数生成器中返回正确的高位数。在不是特殊处理的情况中,将返回正确的低 位数。众所周知,线性同余伪随机数生成器(比如此类所实现的)在其低位的值序列中周期较短。因此,如果 n 是 2 的次幂(幂值较小),则这种特殊情况将大大增加此方法的后续调用所返回的值序列长度。

  参数:

  n – 要返回的随机数的范围。必须为正数。

  返回:

  下一个伪随机数,在此随机数生成器序列中 0(包括)和 n(不包括)之间均匀分布的 int 值。

  经过我的实验,使用该随机产生方法进行的多线程很和谐~~当然在进行随机之前我也又加了一个遍历所有bufs(生产车间或者销售店之一),如果发现其中有buffer满或者空的情况优先选择。但是这样的优先选择策略貌似在Mover上不顶用,在mover上我直接用的随机数,效果也不错。

  不过有一点比较遗憾,就是mover依然是串行的,因为当不加object锁时,我发现很容易死锁。也由于时间关系没有细想,到目前为止,我相当了用栈或者队列的方式来存储buffers来让mover来调用….但是还没有想明白呢。以后再补上吧。

可是却依旧为对方擦去嘴角的油渍。

Java多线程小结–最近Coding的一点心得

相关文章:

你感兴趣的文章:

标签云: