Java同步方法…未同步

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

任何建议将不胜感激。

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

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

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

传递对象同步:

 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的类对象上进行同步,这样更容易

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

synchronized关键字用于线程调用的方法,而不是线程中的方法。

因此,您的线程中定义的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的实例并将其传递给您的线程。

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

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

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