java.lang.Thread.State : BLOCKED (on object monitor)

标签 java multithreading synchronization

我的线程转储中有太多处于阻塞状态的线程。这使得我的应用程序无响应。当我查看代码时,我发现该函数是由于哪个线程进入阻塞状态而同步的。如果不使用此方法同步后,多个线程同时访问同一方法会导致问题,例如一个邮件线程干扰另一个线程。我如何更改我的代码以使我的应用程序不必受到影响。这是我的代码-

//邮件传输类

public final boolean openConnection() throws MailingException {
    boolean flag = false;

    if (transport == null) {

        mailsession = MailSession.getMailSession();
        try {
            transport = (SMTPTransport) mailsession.getNewTransport();
            flag = true;
            // System.out.println("\n--MailTransport.java ------------  Connection is SUccessful -- "+transport.isConnected());
        } catch (MailingException mex) {
            setStatusmessage(new StringBuffer(statusMessages[1]).append(
                    " -- ").append(mailsession.getSmtphost()).append(
                    "<BR> Contact").append(
                    "<A HREF=\"mailto:" + returnPath + "\">").append(
                    "Administrator").append("</A>").toString());
            throw mex;
        }
    } else {
        flag = true;
    }
    return flag;
}

//MailSession类

 public synchronized Transport getNewTransport() throws MailingException
{    
    try
    {
        return getNewTransport(mailtype);

    } catch (MailingException e)
    {
        throw e;
    } catch (Exception e)
    {
        throw new MailingException(" Exception in MailSession.getTransport ", e);
    }
}





 public static MailSession getMailSession()
{
    MailSession _mailSession = MultiTenancyUtil.getTenantMailSession();
    if (_mailSession == null)
    {
        synchronized (MailSession.class)
        {
            if (_mailSession == null)
            {
                _mailSession = new MailSession();
                _mailSession.initialize();
                MultiTenancyUtil.getTenantResources().setMailSession(_mailSession);
            }
        }
    }
    return _mailSession;
}





  public Transport getNewTransport(String type) throws MailingException
{
    Transport transport = null;
    try
    {
        transport = session.getTransport(type); 
        if (StringUtil.isvalidInteger(getSmtpprot()))
        {
            transport.connect(getSmtphost(), Integer.parseInt(getSmtpprot()), username, password);
        } else
        {
            transport.connect(getSmtphost(), username, password);
        }
    } catch (MessagingException ex)
    {
        MailingException mailex = null;
        Exception nex = ex.getNextException();
        if (nex != null)
        {
            if (nex instanceof SocketTimeoutException)
            {
                mailex = new SMTPServerException("Connection to Server Failed. SMTP server does not Exist on host--" + getSmtphost() + " -- Mention the proper Host. Other wise Server is very Slow");
                mailex.setCause(ex);
            }
            if (nex instanceof ConnectException)
            {
                mailex = new SMTPServerException("Connection to Server Failed. Unable to connect to port" + getSmtpprot() + " on SMTP server host---" + getSmtphost() + " -- Mention the proper Server and Port.");
                mailex.setCause(ex);
            }
        }
        if (mailex == null)
        {
            mailex = new SMTPServerException("Connection to Server Failed");
            mailex.setCause(ex);
        }

        throw mailex;
    } catch (Exception ex)
    {
        MailingException mailex = new MailingException("Connection to Server Failed");
        mailex.setCause(ex);
        throw mailex;
    }
    return transport;
}

这是我的线程转储的一部分-

     at javax.mail.Service.connect(Service.java:275)
     at javax.mail.Service.connect(Service.java:156)
     at      com.appnetix.app.util.mail.MailSession.getNewTransport(MailSession.java:199)
     at com.appnetix.app.util.mail.MailSession.getNewTransport(MailSession.java:249)
 locked <0x00000007211b9480> (a com.appnetix.app.util.mail.MailSession)
     at com.appnetix.app.util.mail.MailTransport.openConnection(MailTransport.java:122)
     at com.appnetix.app.util.mail.MailSenderBase.init(MailSenderBase.java:107)
     at com.appnetix.app.util.MailSender.sendMail(MailSender.java:193)
     at com.appnetix.app.util.MailSender.sendMail(MailSender.java:175)

最佳答案

这里有一些提示:

不要在主线程上发送电子邮件。创建一个处理电子邮件的线程池。这很有用,因为通常您不需要等待电子邮件成功发送即可为调用方法提供答案。足以说明我已经收到了您的电子邮件,我会尽快(异步)发送它。

您确定需要同步getNewTransport吗? 尝试重写方法 getNewTransport 以返回新的 Transport 而不使用可变实例变量。这样做可以消除 synchronized 的使用。

关于java.lang.Thread.State : BLOCKED (on object monitor),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40907107/

相关文章:

Python - 线程同时打印弄乱了文本输出

.net - DataRow线程安全吗?如何使用多个线程更新数据表中的单个数据行? -.net 2.0

java - 请求处理失败;嵌套异常是 org.springframework.transaction.CannotCreateTransactionException

java - KeyGenerator 中 AES 与 DES 的 key 大小

java - map View : Could not find class A referenced from method B

operating-system - 为什么我们在生产者消费者问题中需要 2 个信号量变量?

android - 在单独的 Android 设备上同步播放音频

java - 从java自定义excel文件

java - 如何使用 RxJava 2 创建异步事件总线?

multithreading - 高速线程同步