消息队列实现实现一个消息队列需要具备哪些知识

消息队列实现  时间:2021-06-13  阅读:()

消息队列一般用什么技术实现比较好

队列通信中的消息有明显的生命周期,消息有传递的过程,有通知的过程,消息有失效性,有先后关系。

而共享内存没有上面这些特点。

共享内存在使用时要解决互斥的问题。

消息队列的执行顺序到底是怎么样的

消息在消息队列中就是按照进入队列的先后顺序排列的。

线程按照顺序从队列中取出消息并处理。

多个辅助线程,只要保证各个消息是顺序的发送给主线程,就可以保证主线程的处理顺序

在JAVA中怎么实现消息队列

展开全部 java中的消息队列 消息队列是线程间通讯的手段: import java.util.* public class MsgQueue{ private Vector queue = null; public MsgQueue(){ queue = new Vector(); } public synchronized void send(Object o) { queue.addElement(o); } public synchronized Object recv() { if(queue.size()==0) return null; Object o = queue.firstElement(); queue.removeElementAt(0);//or queue[0] = null can also work return o; } } 因为java中是locked by object的所以添加synchronized 就可以用于线程同步锁定对象 可以作为多线程处理多任务的存放task的队列。

他的client包括封装好的task类以及thread类 Java的多线程-线程间的通信2009-08-25 21:58 1. 线程的几种状态 线程有四种状态,任何一个线程肯定处于这四种状态中的一种: 1) 产生(New):线程对象已经产生,但尚未被启动,所以无法执行。

如通过new产生了一个线程对象后没对它调用start()函数之前。

2) 可执行(Runnable):每个支持多线程的系统都有一个排程器,排程器会从线程池中选择一个线程并启动它。

当一个线程处于可执行状态时,表示它可能正处于线程池中等待排排程器启动它;也可能它已正在执行。

如执行了一个线程对象的start()方法后,线程就处于可执行状态,但显而易见的是此时线程不一定正在执行中。

3) 死亡(Dead):当一个线程正常结束,它便处于死亡状态。

如一个线程的run()函数执行完毕后线程就进入死亡状态。

4) 停滞(Blocked):当一个线程处于停滞状态时,系统排程器就会忽略它,不对它进行排程。

当处于停滞状态的线程重新回到可执行状态时,它有可能重新执行。

如通过对一个线程调用wait()函数后,线程就进入停滞状态,只有当两次对该线程调用notify或notifyAll后它才能两次回到可执行状态。

2. class Thread下的常用函数函数 2.1 suspend()、resume() 1) 通过suspend()函数,可使线程进入停滞状态。

通过suspend()使线程进入停滞状态后,除非收到resume()消息,否则该线程不会变回可执行状态。

2) 当调用suspend()函数后,线程不会释放它的“锁标志”。

例11: class TestThreadMethod extends Thread{ public static int shareVar = 0; public TestThreadMethod(String name){ super(name); } public synchronized void run(){ if(shareVar==0){ for(int i=0; i<5; i++){ shareVar++; if(shareVar==5){ this.suspend(); //(1) }}} else{ System.out.print(Thread.currentThread().getName()); System.out.println(" shareVar = " + shareVar); this.resume(); //(2) }} } public class TestThread{ public static void main(String[] args){ TestThreadMethod t1 = new TestThreadMethod("t1"); TestThreadMethod t2 = new TestThreadMethod("t2"); t1.start(); //(5) //t1.start(); //(3) t2.start(); //(4) }} 运行结果为: t2 shareVar = 5 i. 当代码(5)的t1所产生的线程运行到代码(1)处时,该线程进入停滞状态。

然后排程器从线程池中唤起代码(4)的t2所产生的线程,此时shareVar值不为0,所以执行else中的语句。

ii. 也许你会问,那执行代码(2)后为什么不会使t1进入可执行状态呢?正如前面所说,t1和t2是两个不同对象的线程,而代码(1)和(2)都只对当前对象进行操作,所以t1所产生的线程执行代码(1)的结果是对象t1的当前线程进入停滞状态;而t2所产生的线程执行代码(2)的结果是把对象t2中的所有处于停滞状态的线程调回到可执行状态。

iii. 那现在把代码(4)注释掉,并去掉代码(3)的注释,是不是就能使t1重新回到可执行状态呢?运行结果是什么也不输出。

为什么会这样呢?也许你会认为,当代码(5)所产生的线程执行到代码(1)时,它进入停滞状态;而代码(3)所产生的线程和代码(5)所产生的线程是属于同一个对象的,那么就当代码(3)所产生的线程执行到代码(2)时,就可使代码(5)所产生的线程执行回到可执行状态。

但是要清楚,suspend()函数只是让当前线程进入停滞状态,但并不释放当前线程所获得的“锁标志”。

所以当代码(5)所产生的线程进入停滞状态时,代码(3)所产生的线程仍不能启动,因为当前对象的“锁标志”仍被代码(5)所产生的线程占有。

#p#2.2 sleep() 1) sleep ()函数有一个参数,通过参数可使线程在指定的时间内进入停滞状态,当指定的时间过后,线程则自动进入可执行状态。

2) 当调用sleep ()函数后,线程不会释放它的“锁标志”。

例12: class TestThreadMethod extends Thread{ class TestThreadMethod extends Thread{ public static int shareVar = 0; public TestThreadMethod(String name){ super(name); } public synchronized void run(){ for(int i=0; i<3; i++){ System.out.print(Thread.currentThread().getName()); System.out.println(" : " + i); try{ Thread.sleep(100); //(4) } catch(InterruptedException e){ System.out.println("Interrupted"); }}} } public class TestThread{public static void main(String[] args){ TestThreadMethod t1 = new TestThreadMethod("t1"); TestThreadMethod t2 = new TestThreadMethod("t2"); t1.start(); (1) t1.start(); (2) //t2.start(); (3) }} 运行结果为: t1 : 0 t1 : 1 t1 : 2 t1 : 0 t1 : 1 t1 : 2 由结果可证明,虽然在run()中执行了sleep(),但是它不会释放对象的“锁标志”,所以除非代码(1)的线程执行完run()函数并释放对象的“锁标志”,否则代码(2)的线程永远不会执行。

如果把代码(2)注释掉,并去掉代码(3)的注释,结果将变为: t1 : 0 t2 : 0 t1 : 1 t2 : 1 t1 : 2 t2 : 2 由于t1和t2是两个对象的线程,所以当线程t1通过sleep()进入停滞时,排程器会从线程池中调用其它的可执行线程,从而t2线程被启动。

例13: class TestThreadMethod extends Thread{ public static int shareVar = 0; public TestThreadMethod(String name){ super(name); } public synchronized void run(){ for(int i=0; i<5; i++){ System.out.print(Thread.currentThread().getName()); System.out.println(" : " + i); try{ if(Thread.currentThread().getName().equals("t1")) Thread.sleep(200); else Thread.sleep(100); } catch(InterruptedException e){ System.out.println("Interrupted"); }} }} public class TestThread{public static void main(String[] args){ TestThreadMethod t1 = new TestThreadMethod("t1"); TestThreadMethod t2 = new TestThreadMethod("t2"); t1.start(); //t1.start(); t2.start(); }} 运行结果为: t1 : 0 t2 : 0 t2 : 1 t1 : 1 t2 : 2 t2 : 3 t1 : 2 t2 : 4 t1 : 3 t1 : 4 由于线程t1调用了sleep(200),而线程t2调用了sleep(100),所以线程t2处于停滞状态的时间是线程t1的一半,从从结果反映出来的就是线程t2打印两倍次线程t1才打印一次。

#p#2.3 yield() 1) 通过yield ()函数,可使线程进入可执行状态,排程器从可执行状态的线程中重新进行排程。

所以调用了yield()的函数也有可能马上被执行。

2) 当调用yield ()函数后,线程不会释放它的“锁标志”。

例14: class TestThreadMethod extends Thread{ public static int shareVar = 0; public TestThreadMethod(String name){super(name); } public synchronized void run(){for(int i=0; i<4; i++){ System.out.print(Thread.currentThread().getName()); System.out.println(" : " + i); Thread.yield(); }} } public class TestThread{public static void main(String[] args){ TestThreadMethod t1 = new TestThreadMethod("t1"); TestThreadMethod t2 = new TestThreadMethod("t2"); t1.start(); t1.start(); //(1) //t2.start(); (2) } } 运行结果为: t1 : 0 t1 : 1 t1 : 2 t1 : 3 t1 : 0 t1 : 1 t1 : 2 t1 : 3 从结果可知调用yield()时并不会释放对象的“锁标志”。

如果把代码(1)注释掉,并去掉代码(2)的注释,结果为: t1 : 0 t1 : 1 t2 : 0 t1 : 2 t2 : 1 t1 : 3 t2 : 2 t2 : 3 从结果可知,虽然t1线程调用了yield(),但它马上又被执行了。

2.4 sleep()和yield()的区别 1) sleep()使当前线程进入停滞状态,所以执行sleep()的线程在指定的时间内肯定不会执行;yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。

2) sleep()可使优先级低的线程得到执行的机会,当然也可以让同优先级和高优先级的线程有执行的机会;yield()只能使同优先级的线程有执行的机会。

例15: class TestThreadMethod extends Thread{ public static int shareVar = 0; public TestThreadMethod(String name){ super(name); } public void run(){ for(int i=0; i<4; i++){ System.out.print(Thread.currentThread().getName()); System.out.println(" : " + i); //Thread.yield(); (1) /* (2) */ try{ Thread.sleep(3000); } catch(InterruptedException e){ System.out.println("Interrupted"); }}} } public class TestThread{ public static void main(String[] args){ TestThreadMethod t1 = new TestThreadMethod("t1"); TestThreadMethod t2 = new TestThreadMethod("t2"); t1.setPriority(Thread.MAX_PRIORITY); t2.setPriority(Thread.MIN_PRIORITY); t1.start(); t2.start(); } } 运行结果为: t1 : 0 t1 : 1 t2 : 0 t1 : 2 t2 : 1 t1 : 3 t2 : 2 t2 : 3 由结果可见,通过sleep()可使优先级较低的线程有执行的机会。

注释掉代码(2),并去掉代码(1)的注释,结果为: t1 : 0 t1 : 1 t1 : 2 t1 : 3 t2 : 0 t2 : 1 t2 : 2 t2 : 3 可见,调用yield(),不同优先级的线程永远不会得到执行机会。

2.5 join() 使调用join()的线程执行完毕后才能执行其它线程,在一定意义上,它可以实现同步的功能。

例16: class TestThreadMethod extends Thread{ public static int shareVar = 0; public TestThreadMethod(String name){ super(name); } public void run(){ for(int i=0; i<4; i++){ System.out.println(" " + i); try{ Thread.sleep(3000); } catch(InterruptedException e){ System.out.println("Interrupted"); } } } } public class TestThread{ public static void main(String[] args){ TestThreadMethod t1 = new TestThreadMethod("t1"); t1.start(); try{ t1.join(); } catch(InterruptedException e){} t1.start(); } } 运行结果为: 0 1 2 3 0 1 2 3 #p#3. class Object下常用的线程函数 wait()、notify()和notifyAll()这三个函数由java.lang.Object类提供,用于协调多个线程对共享数据的存取。

3.1 wait()、notify()和notifyAll() 1) wait()函数有两种形式:第一种形式接受一个毫秒值,用于在指定时间长度内暂停线程,使线程进入停滞状态。

第二种形式为不带参数,代表waite()在notify()或notifyAll()之前会持续停滞。

2) 当对一个对象执行notify()时,会从线程等待池中移走该任意一个线程,并把它放到锁标志等待池中;当对一个对象执行notifyAll()时,会从线程等待池中移走所有该对象的所有线程,并把它们放到锁标志等待池中。

3) 当调用wait()后,线程会释放掉它所占有的“锁标志”,从而使线程所在对象中的其它synchronized数据可被别的线程使用。

例17: 下面,我们将对例11中的例子进行修改 class TestThreadMethod extends Thread{ public static int shareVar = 0; public TestThreadMethod(String name){ super(name); } public synchronized void run(){ if(shareVar==0){ for(int i=0; i<10; i++){ shareVar++; if(shareVar==5){ try{ this.wait(); //(4) } catch(InterruptedException e){} } } } if(shareVar!=0){ System.out.print(Thread.currentThread().getName()); System.out.println(" shareVar = " + shareVar); this.notify(); //(5) } } } public class TestThread{ public static void main(String[] args){ TestThreadMethod t1 = new TestThreadMethod("t1"); TestThreadMethod t2 = new TestThreadMethod("t2"); t1.start(); //(1) //t1.start(); (2) t2.start(); //(3) }} 运行结果为: t2 shareVar = 5 因为t1和t2是两个不同对象,所以线程t2调用代码(5)不能唤起线程t1。

如果去掉代码(2)的注释,并注释掉代码(3),结果为: t1 shareVar = 5 t1 shareVar = 10 这是因为,当代码(1)的线程执行到代码(4)时,它进入停滞状态,并释放对象的锁状态。

接着,代码(2)的线程执行run(),由于此时shareVar值为5,所以执行打印语句并调用代码(5)使代码(1)的线程进入可执行状态,然后代码(2)的线程结束。

当代码(1)的线程重新执行后,它接着执行for()循环一直到shareVar=10,然后打印shareVar。

#p#3.2 wait()、notify()和synchronized waite()和notify()因为会对对象的“锁标志”进行操作,所以它们必须在synchronized函数或synchronized block中进行调用。

如果在non-synchronized函数或non-synchronized block中进行调用,虽然能编译通过,但在运行时会发生IllegalMonitorStateException的异常。

例18: class TestThreadMethod extends Thread{ public int shareVar = 0; public TestThreadMethod(String name){ super(name); new Notifier(this); } public synchronized void run(){ if(shareVar==0){ for(int i=0; i<5; i++){ shareVar++; System.out.println("i = " + shareVar); try{ System.out.println("wait......"); this.wait(); } catch(InterruptedException e){} }} } } class Notifier extends Thread{ private TestThreadMethod ttm; Notifier(TestThreadMethod t){ ttm = t; start(); } public void run(){ while(true){ try{ sleep(2000); } catch(InterruptedException e){} /*1 要同步的不是当前对象的做法 */ synchronized(ttm){ System.out.println("notify......"); ttm.notify(); }} } } public class TestThread{ public static void main(String[] args){ TestThreadMethod t1 = new TestThreadMethod("t1"); t1.start(); } } 运行结果为: i = 1 wait...... notify...... i = 2 wait...... notify...... i = 3 wait...... notify...... i = 4 wait...... notify...... i = 5 wait...... notify...... 4. wait()、notify()、notifyAll()和suspend()、resume()、sleep()的讨论 4.1 这两组函数的区别 1) wait()使当前线程进入停滞状态时,还会释放当前线程所占有的“锁标志”,从而使线程对象中的synchronized资源可被对象中别的线程使用;而suspend()和sleep()使当前线程进入停滞状态时不会释放当前线程所占有的“锁标志”。

2) 前一组函数必须在synchronized函数或synchronized block中调用,否则在运行时会产生错误;而后一组函数可以non-synchronized函数和synchronized block中调用。

4.2 这两组函数的取舍 Java2已不建议使用后一组函数。

因为在调用suspend()时不会释放当前线程所取得的“锁标志”,这样很容易造成“死锁”。

消息队列为什么用redis实现

展开全部 redis只是提供一个高性能的、原子操作的分布式队列实现。

具体的业务还是得需要你自己定制。

你的需求实际上是一个变形的生产者-消费者实现。

对于此类需求,主要是将请求和实际的处理过程解耦,一般都是采取异步的方式来通知请求方,这跟用不用redis其实没有多大的关系。

一般的实现方法是你需要将用户的请求封装成一个Task,然后将这个Task再push到redis队列,然后后端的worker.php完全可以多进程、多线程的并发处理Task并将处理结果回调给请求方。

这里唯一麻烦点的就是这个Task的设计,需要能够包含请求信息(请求内容,请求方标识等等).

实现一个消息队列需要具备哪些知识

各位,我再解释一下:我的意思是用 CreateThread创建一个thread,然后主线程发Postmessage,我的线程用PeekMessage收。

发明主线程postmessage时报“线程消息队列没有创建”的错。

可是在SDK HELP中说PeekMessage可以主动创建消息队列。

(这是线程本身的消息队列,和什么体系消息队列什么的不相干的)

弘速云20.8元/月 ,香港云服务器 2核 1g 10M

弘速云元旦活动本公司所销售的弹性云服务器、虚拟专用服务器(VPS)、虚拟主机等涉及网站接入服务的云产品由具备相关资质的第三方合作服务商提供官方网站:https://www.hosuyun.com公司名:弘速科技有限公司香港沙田直营机房采用CTGNET高速回国线路弹性款8折起优惠码:hosu1-1 测试ip:69.165.77.50​地区CPU内存硬盘带宽价格购买地址香港沙田2-8核1-16G20-...

腾讯云爆款秒杀:1C2G5M服务器38元/年,CDN流量包6元起

农历春节将至,腾讯云开启了热门爆款云产品首单特惠秒杀活动,上海/北京/广州1核2G云服务器首年仅38元起,上架了新的首单优惠活动,每天三场秒杀,长期有效,其中轻量应用服务器2G内存5M带宽仅需年费38元起,其他产品比如CDN流量包、短信包、MySQL、直播流量包、标准存储等等产品也参与活动,腾讯云官网已注册且完成实名认证的国内站用户均可参与。活动页面:https://cloud.tencent.c...

LetBox:美国洛杉矶/新泽西AMD大硬盘VPS,10TB流量,充值返余额,最低3.3美元两个月

LetBox此次促销依然是AMD Ryzen处理器+NVME硬盘+HDD大硬盘,以前是5TB月流量,现在免费升级到10TB月流量。另外还有返余额的活动,如果月付,月付多少返多少;如果季付或者半年付,返25%;如果年付,返10%。依然全部KVM虚拟化,可自定义ISO系统。需要大硬盘vps、大流量vps、便宜AMD VPS的朋友不要错过了。不过LetBox对帐号审核严格,最好注册邮箱和paypal帐号...

消息队列实现为你推荐
换脸软件手机软件有没有可以换脸的软件,或者有没有会ps的大神???在线等orderbydescSQL里面的order by语句是干什么用的?Honeypotnc如何使用以图搜人怎样人肉搜人?只知道他名字和当初居住的地址应用雷达雷达是什么东西企业资源管理系统企业内部管理系统有哪些star413匡威jack star 的后标是不是真的?如图熊猫烧香病毒下载谁知道熊猫烧香病毒天翼校园宽带天翼校园宽带 是怎么算时间的 一个月 是指从办理那天开始 往后 30天是一个月吗 还是 办理的那天所在的那个山东省教育云平台服务山东教育云平台怎么这么烂
虚拟主机99idc 深圳域名空间 申请免费域名 arvixe 好看的桌面背景大图 php探针 tk域名 彩虹ip 华为4核 京东商城双十一活动 cdn加速是什么 免费网络空间 杭州电信 服务器托管价格 alexa世界排名 godaddy退款 zencart安装 带宽测速 赵荣 ddos攻击器 更多