您当前的位置:首页 > 互联网教程

java exchanger用在什么场景

发布时间:2025-05-20 21:24:32    发布人:远客网络

java exchanger用在什么场景

一、java exchanger用在什么场景

1、Exchanger是在两个任务之间交换对象的栅栏。当两个任务进入栅栏时,它们各自拥有一个对象,当它们离开时,它们都拥有对方的对象。Exchanger的典型应用场景是:一个任务在创建对象,而这些对象的生产代价很高,另一个任务在消费这些对象。通过这种方式,可以有更多的对象在被创建的同时被消费。

2、为了演示Exchanger类,我们将创建生产者和消费者任务。ExchangerProducer和ExchangerConsumer使用一个List<Fat>作为要求交换的对象,它们都包含一个用于这个List<Fat>的Exchanger。当你调用Exchanger.exchange()方法时,它将阻塞直至对方任务调用它自己的exchange()方法,那时,这两个exchange()方法将同时完成,而List<Fat>被交换:

3、import java.util.concurrent.CopyOnWriteArrayList;

4、import java.util.concurrent.Exchanger;

5、import java.util.concurrent.ExecutorService;

6、import java.util.concurrent.Executors;

7、import java.util.concurrent.TimeUnit;

8、class ExchangerProducer implements Runnable{

9、private List<Fat> holder;

10、private Exchanger<List<Fat>> exchanger;

11、public ExchangerProducer(Exchanger<List<Fat>> exchanger, List<Fat> holder){

12、for(int i= 0;i< ExchangerDemo.size; i++){

13、holder= exchanger.exchange(holder);

14、} catch(InterruptedException e){

15、System.out.println("Producer stopped.");

16、class ExchangerConsumer implements Runnable{

17、private List<Fat> holder;

18、private Exchanger<List<Fat>> exchanger;

19、public ExchangerConsumer(Exchanger<List<Fat>> exchanger, List<Fat> holder){

20、holder= exchanger.exchange(holder);

21、//在循环内删除元素,这对于CopyOnWriteArrayList是没有问题的

22、System.out.println("Exchanged count="+ num);

23、} catch(InterruptedException e){

24、System.out.println("Consumer stopped. Final value:"+ value);

25、public static void main(String[] args) throws Exception{

26、ExecutorService exec= Executors.newCachedThreadPool();

27、List<Fat> producerList= new CopyOnWriteArrayList<>();

28、List<Fat> consumerList= new CopyOnWriteArrayList<>();

29、Exchanger<List<Fat>> exchanger= new Exchanger<>();

30、exec.execute(new ExchangerProducer(exchanger, producerList));

31、exec.execute(new ExchangerConsumer(exchanger, consumerList));

32、TimeUnit.SECONDS.sleep(delay);

33、private static int counter= 1;

34、private final int id= counter++;

35、for(int i= 1; i<10000; i++){

36、d+=(Math.PI+ Math.E)/(double)i;

37、public void print(){System.out.println(this);}

38、public String toString(){return"Fat id="+ id;}

39、Consumer stopped. Final value: Fat id=88300

40、在main()中,创建了用于两个任务的单一的Exchanger,以及两个用于互换的CopyOnWriteArrayList。这个特定的List变体允许列表在被遍历的时候调用remove()方法,而不会抛出ConcurrentModifiedException异常。ExchangerProducer将填充这个List,然后将这个满列表跟ExchangerConsumer的空列表交换。交换之后,ExchangerProducer可以继续的生产Fat对象,而ExchangerConsumer则开始使用满列表中的对象。因为有了Exchanger,填充一个列表和消费另一个列表便同时发生了。

二、《RabbitMQ系列》之RabbitMQ的4种Exchange

1、大家好,本文将介绍RabbitMQ中的4种Exchange:direct、topic、fanout、headers。RabbitMQ拥有4种Exchange,它们是direct、topic、fanout、headers,还有默认的direct Exchange。在实际应用中,direct、topic、fanout是使用最频繁的类型。接下来,我们将通过代码示例,详细介绍这4种Exchange的使用方法与应用场景。

2、Direct Exchange基于routing key与队列的绑定。生产者发送的消息根据指定的routing key,被路由到一个或多个队列。如果交换机绑定了多个队列,则每条消息都会被路由到每个队列中。

3、@EnableRabbit注解用于开启基于注解的RabbitMQ配置。

4、convertAndSend方法用于向RabbitMQ发送消息,其中第一个参数"directExchange"指定交换机名称,第二个参数"rk.001"为routing key,第三个参数为消息内容。

5、@RabbitListener注解用于指定消息消费方法,参数queues指定监听的队列,bindings用于指定与队列的绑定关系。

6、Topic Exchange类似于Direct Exchange,但使用模式匹配的routing key。routing key可以包含通配符,如`*.orange.*`或`lazy.#`,其中`*`代表一个单词,`#`代表多个单词。

7、生产者发送消息时,指定不同的routing key;消费者监听多个队列,通过模式匹配的routing key消费消息。

8、Fanout Exchange不使用routing key,将消息路由到所有与其绑定的队列。与Direct Exchange类似,绑定了Fanout Exchange的队列都会接收到全量消息。

9、生产者无需指定routing key,直接发送消息到Fanout Exchange;消费者监听Fanout Exchange,接收全量消息。

10、Headers Exchange根据消息的头部信息进行路由。配置时需指定x-match参数,用于控制匹配规则。

11、生产者发送消息时指定头部信息;消费者监听队列,通过头部信息匹配消费消息。

12、-**Direct Exchange**:适用于业务数据直接传输并消费的场景,如不同业务模块间的消息交互。

13、-**Topic Exchange**:适用于涉及分类或标记的新闻更新,以及后台任务处理。

14、-**Fanout Exchange**:适用于广播消息的场景,如群聊功能、多人在线游戏更新等。

15、-**Headers Exchange**:适用于routing key复杂且需要灵活匹配的场景。

16、以上就是RabbitMQ中4种Exchange的介绍与使用方法。通过灵活运用这些Exchange,可以实现高效、灵活的消息处理流程。如有疑问或需要进一步讨论,欢迎在评论区留言交流。我是@明人只说暗话,感谢阅读!

三、如何使用Java发送qq邮件

首先,邮件的发送方要开启POP3和SMTP服务--即发送qq邮件的账号要开启POP3和SMTP服务

5.找到:POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务—点击开启

7.稍等一会,很得到一个授权码!–注意:这个一定要记住,一会用到

import javax.mail.MessagingException;

import javax.mail.internet.AddressException;

import javax.mail.internet.InternetAddress;

import javax.mail.internet.MimeMessage;

import javax.mail.internet.MimeMessage.RecipientType;

public static void main(String[] args) throws AddressException, MessagingException{

Properties properties= new Properties();

properties.put("mail.transport.protocol","smtp");//连接协议

properties.put("mail.smtp.host","smtp.qq.com");//主机名

properties.put("mail.smtp.port", 465);//端口号

properties.put("mail.smtp.auth","true");

properties.put("mail.smtp.ssl.enable","true");//设置是否使用ssl安全连接---一般都使用

properties.put("mail.debug","true");//设置是否显示debug信息 true会在控制台显示相关信息

Session session= Session.getInstance(properties);

Message message= new MimeMessage(session);

message.setFrom(new InternetAddress("123456789@qq.com"));

//设置收件人地址 message.setRecipients( RecipientType.TO, new InternetAddress[]{ new InternetAddress("987654321@qq.com")});

message.setSubject("这是第一封Java邮件");

message.setText("内容为:这是第一封java发送来的邮件。");

Transport transport= session.getTransport();

transport.connect("123456789@qq.com","vvctybgbvvophjcj");//密码为刚才得到的授权码

//发送邮件 transport.sendMessage(message, message.getAllRecipients());

下面是我收到邮件的截图,当然我把源码中的邮件地址都是修改了,不是真实的,你们测试的时候,可以修改能你们自己的邮箱。最后,祝你也能成功,如果有什么问题,可以一起讨论!

得到的授权码一定要保存好,程序中要使用