2012-11-13 148 views
2

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

任何意见将不胜感激。

请参考下面的方法造成我的麻烦:

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()); 
    } 
} 

然后run方法:

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(); 
     } 
    } 
} 
} 
+0

请发布您的代码。 – Thinhbk

+0

最好是发布你的代码而不是描述它。 – hmjd

+0

'System.out.println(“***************************************** ************************************“);'你不打印太多星号吗? – dorukayhan

回答

5

你的对象两个线程可以访问的,因为现在你正在使用的对象实例,你是要同步的事业永远不会有效果,因为这两个线程只有留在他们里面的范围,因为要同步方法据我了解你的问题。你可以在自己的创作通过一个简单的对象,以两个线程和格式化这样

你的方法传递对象同步:

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

保存在Gmail类的引用:

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中的CT,也可能是更容易

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

的​​关键字的推移线程调用的方法,而不是方法在线程中。

所以,你readMail方法,它是在你的线程定义,必须调用所有的线程使用一些其他的方法,被定义在其他地方,你同步方法。

因此,创建一个类

public class MailHelper { 
    public static void synchronized doRead(store) throws MessagingException, IOException { 
     // all your readMail code here, except pass in the store 
    } 
} 

,并在你的线程类

public void readMail() throws MessagingException, IOException { 
    // get your store 
    MailHelper.doRead(store); 
} 

注意,你可以对MailHelper方法不是静态的,那么你就必须创建MailHelper的一个实例并传递给你的线程。

+0

线程调用的方法是readMail,它恰好在gmail类中。没有方法调用readMail,除了这个 – Programatt

+1

发布你的代码... – hvgotcodes

+0

你能解释一下store参数吗?我不太明白 – Programatt

2

当您同步readmail将()的方法,那么只有一次一个线程可以访问对象 readmail将()方法。如果使用readMail()方法有两个不同类型的GMail对象实例,则两个线程可以同时访问它们(并行)。

换句话说,阻止readMail()方法执行的信号实际上是GMail对象。有了两个不同的对象实例,你有两个不交互的信号量。

如果您只有一个具有同步readMail()方法的GMail对象实例,它会起作用。然后一次只有一个线程可以访问它。