直接上代码
<?php
interface Sender {
public function send($message);
}
interface MessageQueue {
public function pop();
}
class SendThread extends Thread {
private $sender;
private $messageQueue;
protected $times;
private $runtime;
private $isStop;
public function __construct(Sender $sender, MessageQueue $messageQueue, $times) {
$this->sender = $sender;
$this->messageQueue = $messageQueue;
$this->times = $times;
$this->runtime = 0;
$this->isStop = false;
}
public function run() {
while (!$this->isStop) {
$runtime = 0;
for ($i = 0; $i < $this->times; ++$i) {
if (!$this->isStop) {
$message = $this->messageQueue->pop();
$start = microtime(true);
$this->sender->send($message);
$end = microtime(true);
$runtime += ($end - $start);
}
}
$this->runtime = $runtime;
}
}
public function stop() {
$this->isStop = true;
}
public function getRuntime() {
return $this->runtime;
}
}
abstract class ManageThread extends Thread {
private $size;
private $max;
private $min;
private $sleepTime;
protected $times;
private $avgRuntime;
private $isStop;
public function __construct($size, $max, $min, $sleepTime, $times) {
$this->size = $size;
$this->max = $max;
$this->min = $min;
$this->isStop = false;
$this->sleepTime = $sleepTime;
$this->times = $times;
$this->avgRuntime = 0;
}
public function run() {
$threadArray = array();
for ($i = 0; $i < $this->size; ++$i) {
$thread = $this->getNewSendThread();
$threadArray[$i] = $thread;
$thread->start();
}
while (!$this->isStop) {
sleep($this->sleepTime);
$sum = 0;
for ($i = 0; $i < $this->size; ++$i) {
$thread = $threadArray[$i];
$sum += $thread->getRuntime();
}
$this->avgRuntime = $sum / $this->size;
if ($this->avgRuntime > $this->max && $this->size > 1)
{
$threadArray[$this->size - 1]->stop();
$threadArray[$this->size - 1] = null;
--$this->size;
}
if ($this->avgRuntime < $this->min)
{
$threadArray[$this->size] = $this->getNewSendThread();
++$this->size;
}
}
for ($i = 0; $i < $this->size; ++$i) {
$thread = $threadArray[$i];
$thread->stop();
}
}
public function stop() {
$this->isStop = true;
}
abstract protected function getNewSendThread();
public function getAvgRuntime() {
return $this->avgRuntime;
}
public function getSize() {
return $this->size;
}
}
class MessegeSender implements Sender {
public function send($message) {
sleep(1); //响应时间
}
}
class ICQMessageQueue implements MessageQueue {
public function pop() {
return "message";
}
}
class MyManageThread extends ManageThread {
protected function getNewSendThread() {
return new SendThread(new MessegeSender(), new ICQMessageQueue(), $this->times);
}
}
$manageThread = new MyManageThread(10, 10, 5, 20, 10);
$manageThread->start();
for ($i = 0; $i < 20; ++$i) {
echo $manageThread->getAvgRuntime(), ' ', $manageThread->getSize(), "\n";
sleep(10);
}
$manageThread->stop();
$manageThread->join();