Java同步方法...未同步 [英] Java Synchronized method...not synchronized

查看:107
本文介绍了Java同步方法...未同步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于我目前的java练习,我必须从2个不同的Gmail帐户获取邮件。我通过创建我的gmail类的新实例来完成此操作。 gmail类扩展了线程,在其中有一个同步方法readMail(),它获取邮件并打印它。这个readMail方法由run方法在while(true)循环中调用,然后它休眠30秒,这个想法是它每30秒获取一次邮件。但是,synchronized方法似乎不起作用。线程互相中断,并且该方法在其他线程中断并开始打印之前不打印消息的所有项目。

For my current java exercise, I have to get mail from 2 different gmail accounts. I have done this by creating new instances of my gmail class. The gmail class extends thread, and within it there is a synchronized method readMail() which gets the mail and prints it. This readMail method is called by the run method in a while(true) loop, and then it sleeps for 30 seconds, the idea being that it gets mail every 30 seconds. However, the synchronized method does not seem to work. The threads interrupt each other and the method does not print all the items of a message before the other thread interrupts and starts printing.

任何建议都将不胜感激。

Any advice would be greatly appreciated.

请看下面给我带来麻烦的方法:

Please see the method below that is causing me trouble:

public synchronized void readMail() throws MessagingException, IOException {
    Folder inbox = store.getFolder("Inbox");
    inbox.open(Folder.READ_ONLY);
    messages = inbox.getMessages();
    // System.out.println("No of Messages : " + inbox.getMessageCount());
    // System.out.println("No of Unread Messages : "
    // + inbox.getUnreadMessageCount());

    for (int i = 0; i < inbox.getUnreadMessageCount(); i++) {

        System.out
                .println("*****************************************************************************");
        System.out.println("NEW MESSAGE " + (i + 1) + ":");
        msg = messages[i];
        // System.out.println(msg.getMessageNumber());
        // Object String;
        // System.out.println(folder.getUID(msg)

        String subject = msg.getSubject();

        System.out.println("Subject: " + subject);
        System.out.println("From: " + msg.getFrom()[0]);
        System.out.println("To: " + msg.getAllRecipients()[0]);
        System.out.println("Date: " + msg.getReceivedDate());
        System.out.println("Size: " + msg.getSize());
        // System.out.println(msg.getFlags());
        // System.out.println("Body: \n"+ msg.getContent());
        // System.out.println(msg.getContentType());
    }
}

然后运行方法:

    public void run() {
    while (true) {

        try {
            readMail();
        } catch (MessagingException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        try {
            sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
}


推荐答案

你应该在两个线程都可以访问的对象上同步你的方法,因为你现在正在使用你所在的对象实例来同步哪个原因永远不会有效,因为两个线程只保留据我了解你的问题,在他们的范围内。您可以在创建时将一个简单的Object传递给两个线程,并重新格式化您的方法,如此

you should synchronize your method on an object both threads have access to, because right now you are using the object instance you are in to synchronize which of cause will never have an effect because both Threads only stay inside their on scope as far as I understand your question. You could pass an simple Object to both threads at their creation and reformat your method like this

传递对象以进行同步:

public static void main(String[] args){
     Object obj = new Object();
     gmail g1 = new gmail(obj);
     gmail g2 = new gemail(obj);
     // more code
}

在gmail类中保存引用:

save reference in gmail class:

public class gmail extends Thread{
    private Object sharedObject;

    public gmail( Object synchronizer){
          sharedObject = synchronzier;
    }

同步:

public void readMail(){
   synchronized( sharedObject ){
       // your method code goes here
   }
}

对于此示例,同样可以在gmail的类对象上进行同步,并且更加轻松

For this Example synchronizing on the class object of gmail is also possible and is even more easy

public void readMail(){
   synchronized( this.getClass() ){
       // your method code goes here
   }
}

这篇关于Java同步方法...未同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆