关于synchronized 的问题
最近对发送mail部分的程序进行改造,原来好好的,修改后发现web服务起来之后只能发送一封,就发布出去了。
只是改造了一下同步块,是在想不明白,大家帮忙看看吧~
原来好用的程序:
public class MailSendHandler implements Runnable { private static MailSendHandler me = null; /** * Log4j Logger对象创建 */ private static Logger logger = null; /** * 关闭默认构造函数 */ private MailSendHandler() { } /** * 唯一实例化接口 * @return */ public static MailSendHandler getInstance() { if (null == me) { synchronized (MailSendHandler.class) { if (null == me) { me = new MailSendHandler(); if (logger == null) { logger = Logger.getLogger(MailSendHandler.class); } } } } return me; } /** * 全局静态变量 */ /** 待发送邮件队列*/ private static LinkedQueue<QueueValue> linkedQueue; /** 线程是否在进行中*/ private static boolean isRun = false; /** * 邮件发送主程序 * @param args */ private static void main(String[] args) { boolean bForever = true; QueueValue queueValue = null; Mail email = null; MailSender mailSender = null; try { while (bForever) { // 如果队列中没有对象了,则不再执行 if(linkedQueue.isEmpty()){ break; } else { queueValue = linkedQueue.get(); email = queueValue.getMail(); mailSender = queueValue.getMailSender(); mailSender.send(email); } } } catch (Exception e) { logger.error(e); } finally { isRun = false; } } /** * 线程启动接口 */ public void run() { MailSendHandler.main(null); } /** * 用户接口,发送邮件的监听器 * @param mailSenderP * @param email */ public void listen(QueueValue queueValue) { if (linkedQueue == null) { synchronized (LinkedQueue.class) { if (null == linkedQueue) { linkedQueue = new LinkedQueue<QueueValue>(); } } } linkedQueue.put(queueValue); // 如果线程正在运行中则不在另起线程。 if (!isRun) { Thread t = new Thread(me); t.start(); isRun = true; } } }
修改后,不好用的source:
public class MailSendHandler implements Runnable { private static MailSendHandler me = null; /** * Log4j Logger对象创建 */ private static Logger logger = null; /** * 关闭默认构造函数 */ private MailSendHandler() { } /** * 唯一实例化接口 * @return */ public static MailSendHandler getInstance() { if (null == me) { synchronized (MailSendHandler.class) { if (null == me) { me = new MailSendHandler(); if (logger == null) { logger = Logger.getLogger(MailSendHandler.class); } } } } return me; } /** * 全局静态变量 */ /** 待发送邮件队列*/ private static LinkedQueue<QueueValue> linkedQueue; /** 线程是否在进行中*/ private static boolean isRun = false; /** * 邮件发送主程序 * @param args */ private static void main(String[] args) { boolean bForever = true; QueueValue queueValue = null; Mail email = null; MailSender mailSender = null; try { while (bForever) { synchronized (LinkedQueue.class) { // 如果队列中没有对象了,则不再执行 if(linkedQueue.isEmpty()){ break; } else { queueValue = linkedQueue.get(); email = queueValue.getMail(); mailSender = queueValue.getMailSender(); mailSender.send(email); } } } } catch (Exception e) { logger.error(e); } finally { isRun = false; } } /** * 线程启动接口 */ public void run() { MailSendHandler.main(null); } /** * 用户接口,发送邮件的监听器 * @param mailSenderP * @param email */ public void listen(QueueValue queueValue) { if (linkedQueue == null) { synchronized (LinkedQueue.class) { if (null == linkedQueue) { linkedQueue = new LinkedQueue<QueueValue>(); } linkedQueue.put(queueValue); } } // 如果线程正在运行中则不在另起线程。 if (!isRun) { Thread t = new Thread(me); t.start(); isRun = true; } } }
主要修改部分就是在操作队列的时候加入同步线程锁而已,为什么会导致只能一次好用呢?
PS:修改点在main方法和listen方法。
真是奇怪~
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
引用来自#5楼“烈冰”的帖子
看不出改了哪里-_-||
建议看一下包java.util.concurrent里的class,用这些api处理同步。以前写过一个多线程的爬虫就是用里面的class,好用
看不出改了哪里-_-||
建议看一下包java.util.concurrent里的class,用这些api处理同步。以前写过一个多线程的爬虫就是用里面的class,好用
你只不过是希望得到一个在多线程环境下的单例而已 可以看看单例模式的多线程环境下的实现吧 我对这个也是不甚了解的~
这个确实是程序bug,修改如下:
如果这部分修改后,整体的synchronized 操作是不是就没有问题了呢?
或者说,这样设计是否合理呢?
你listen 改完后,只有在
linkedQueue被第一次实例化的时候才调用put操作.... 你的queue里应该只有一个值吧