terça-feira, 3 de setembro de 2013

THREADS



A maioria dos sistemas operacionais de hoje são baseados em computadores com apenas um processador que executam várias tarefas simultâneas. Ou seja, vários processos que compartilham do uso da CPU tomando certas fatias de tempo para a sua execução. A esta capacidade é denominado o termo multiprocessamento(multithreading).

Teoricamente existe uma grande proteção para que um processo não afete a execução de outro, modificando. Este alto grau de isolamento reduz os desagradáveis GPF's (General Protection Fault), pois o sistema se torna mais robusto. Em contrapartida, o início de cada processo é bastante custoso em termos de uso de memória e desempenho, e o mecanismo de troca de mensagens entre os processos é mais complexo e mais lento, se comparado a um único programa acessando a própria base de dados.
Uma solução oferecida pelos construtores de sistemas operacionais foi o uso de Threads. A Thread pode ser vista como um subprocesso de um processo, que permite compartilhar a sua área de dados com o programa ou outras Threads. O início de execução da Thread é muito mais rápido do que um processo e o acesso a sua área de dados funciona como um único programa.
Existem basicamente duas abordagens para a implementação das Threads na JVM:
  • A utilização de mecanismos nativos de operação de S.O.
  • Aimplementação completa da operação de thread na JVM. 
A diferença básica é que as threads com mecanismos nativos do S.O. são mais rápidas. Em contrapartida, as implementadas pela JVM têm independência completa de plataforma.
O suporte a múltiplas linhas de execução permite que múltiplos processamentos ocorram em "paralelo" (em computadores com um processador, os threads não são executados em paralelo e, sim, concorrentemente).



Existe duas formas de utilização de Threads em JAVA, a primeira forma é a mais simples de todas e consiste em criar uma classe que herde de java.lang.Thread. Uma vez criada esta classe, basta criar um objeto da mesma e chamar o método start.
Este método registrará a thread no escalonador.
A segunda forma e implementando uma interface da classe Runnable, quando não ser conveniente criar uma subclasse de Thread ou não ser possivel devido ao mecanismo de herança implementado em Java.
Em Runnable, não mais utilizamos uma subclasse de java.lang.Thread. Ao invés disso, utilizamos um objeto da própria classe java.lang.Thread. No entanto definimos, através do construtor da classe, que código a thread deveria executar. O objeto que é passado como argumento para o construtor deve implementar a interface Runnable. Dessa forma, a thread irá chamar o método run do objeto passado como parâmetro no momento que ela for autorizada a utilizar o processador. A classe Imprime implementa a interface Runnable. Se tivéssemos utilizado o construtor vazio da classe Thread, o código compilaria normalmente. Mas ao invés de executar o método run da classe Imprime, a thread executaria o método run da classe Thread (que não faz nada).

public class jThreads
{
    public jThreads() {
    }
   
    public static void main(String[] args) {
            Thread threadComHeranca = new Tarefa1();
Thread threadComRunnable = new Thread(new Tarefa2()); // no caso de Runnable é obrigatório utilizar new Thread()
            threadComHeranca.start();
            threadComRunnable.start();
    }
}
class Tarefa1 extends Thread {
            // Thread utilizando herança estendendo a classe Thread
            public void run() {
                        for(int i=0; i<1000; i++){
                        // sleep (milseg) coloca a thread em estado bloqueado
                                   try {
                                               sleep(100);
                                    } catch (InterruptedException e) { }
                                   System.out.println("Usando herança");
                        }
            }
}
class Tarefa2 implements Runnable {
            // Thread utilizando implementação da interface Runnable
            public void run() {
                        for(int i=0; i<1000; i++){
                                   try {
                  Thread.sleep(100); // no caso de Runnable é obrigatorio utilizar Thread.sleep()
            } catch (InterruptedException e) { }
                                   System.out.println("Usando Runnable");
                        }
            }
}



O ciclo de vida de uma thread tem cinco estados básicos:

  • Novo: Quando é criada, ou seja, quando é alocada área de memória para ela através do operador new. Ao ser criada, a thread passa a ser registrada dentro da JVM, para que a mesma possa ser executada.
  • Executável: Quando for ativada. O processo de ativação é originado pelo método start(). É importante frisar que uma thread executável não está necessariamente sendo executada, pois quem determina o tempo de sua execução é a JVM ou o S.O.
  • Bloqueado: Quando for desativada. Para desativar uma thread é necessário que ocorra uma das quatro operações a seguir:
    • Foi chamado o método suspend() da thread;
    • A thread chamou os algum dos medotos:
      • Sleep(millseg) – Aguarda xx miliseg para executar prox.linha
      • Wait() – Fica aguardando um notify()
      • Yield() – Pausa e da passagem a outras thread com mesma prioridade
    • A thread chamou uma operação de I/O que bloqueia a CPU.
    • Para a thread sair do estado de bloqueado e voltar para o estado de executável, uma das seguintes ações deve ocorrer, em oposição às ações acima:
      • Retorna após o tempo especificado, caso a thread estiver adormecida;
      • Retorna através do método resume(), caso a thread tiver sido suspensa;
      • Retorna com método notify() (ou notifyAll()), caso a thread estiver em espera;
      • Retorna após a conclusão da operação de I/O.
  • Encerrado
    Quando encerrar a sua execução e, isto pode ocorrer pelo término do método run(), ou pela chamada explícita do método stop().
    Nunca o método run deve ser chamado diretamente. Isto é feito pelo método start da Thread. Ao terminar a execução de uma thread, ou seja quando o método run é finalizado, a thread é considerada morta não podendo portanto ser reiniciada. O objeto que representa a thread ainda existe logo pode-se invocar qualquer um de seus métodos com exceção do método start.


Java cria a ilusão de que várias linhas estão em execução simultaneamente, alternando rapidamente o controle do processador entre as linhas. Dependendo do propósito do programa, poderá haver ocasiões em que seja necessário dar preferência ao processamento de determinadas Threads.
As threads sempre iniciam sua execução com a prioridade herdada da superclasse, que por default é igual a 5 (Thread.NORM_PRIORITY). Porém, o programador pode alterar a prioridade da thread como convier, dentro do range de prioridades:
Thread.MIN_PRIORITY  [1]
Thread.MAX_PRIORITY [10]
Thread.NORM_PRIORITY [5]

Escalonamento mostra os mecanismos que determinam como os threads executáveis (runnable) irão utilizar tempo de CPU, que pode ser alterada com setPriority(int p) e pode ser lida com getPriority().
  
Sincronismo entre threads

A primeira forma de sincronização: SYNCHONIZED

Dentro de um programa, segmentos de código que acessam os mesmos dados usando threads diferentes e concorrentes são chamados de regiões críticas ou seções críticas e podem ser um bloco de statements ou um método inteiro e deve ser identificada com a palavra synchronized.

public class CubbyHole {
    private int contents;
    private boolean available = false;

    public synchronized int get(int who) {
    } 
    public synchronized void put(int who, int value) {
    }
}

Ao entrar num método synchronized, o thread que chamou o método trava o objeto cujo método foi chamado, se outro thread chamar um método synchronized do mesmo objeto, ele vai esperar até o primeiro liberar o lock.

Segunda forma de sincronização: NOTIFYALL, NOTIFY e WAIT

public final void notify( )
Acorda uma única thread na fila de espera   

public final void notifyAll( )
Acorda todas as threads na fila de espera

public final void wait( ) 

A thread espera (dorme) a notificação de uma outra thread. Quando notificada, a thread deve ganhar novamente o lock  associado com o objeto  

domingo, 1 de setembro de 2013

JavaMail



É uma framework para envio, recebimento e manipulação de e-mais, com implementações para IMAP e SMTP.

Ambiente básico para utilização do JavaMail:
JDK (Ambiente de desenvolviemento do JDK)
JavaMail (mail.jar), JAF (activation.jar)
Qmail (servidor de mails)
import javax.activation.*;
import javax.mail.internet.*;
import java.util.*;
import javax.mail.*;
public class smtp_jm
{         
            public static void main(String args[]) throws Exception
            {
                        Properties props = new Properties();
                        props.put("mail.smtp.host", "smtp.mail.yahoo.com.br");
// definicao do host
                        props.put("mail.smtp.auth", "true");
// determina se tera autenticaçao                  
                        Authenticator auth = new SMTPAuthenticator();   // autenticador                          
                        Session s = Session.getInstance(props,auth); 
                        s.setDebug(true); // em caso de nao querer debugaçao suprima esta linha
                        MimeMessage message = new MimeMessage(s);
                        InternetAddress from = new InternetAddress("lilith_nefelin@yahoo.com.br");
                        message.setFrom(from);                       
                        InternetAddress to = new InternetAddress("helloween_salvation@yahoo.com.br");
                        message.addRecipient(Message.RecipientType.TO, to); 
                        message.setSubject("E-Mail enviado a partir do JavaMail.");
                        message.setText("Este é o texto da mensagem enviada através do JavaMail!");
                        Transport.send(message);
            }
}
class SMTPAuthenticator extends Authenticator
{   
            public PasswordAuthentication getPasswordAuthentication()
            {   
                        String username = "lilith_nefelin";   
                        String password = "manuka";   
                        return new PasswordAuthentication(username, password);   
            }   
 }


Para a leitura de e-mails de um servidor que utilize o protocolo POP, é necessário que a mensagem do servidor seja copiada e aberta localmente.
Para um servidor IMAP, nos estaremos trabalhando com o servidor diretamente.


import javax.activation.*;
import javax.mail.internet.*;
import java.util.*;
import javax.mail.*;
public class pop_jm
{         
            public static void main(String args[]) throws Exception
            {
                        String host= "pop.mail.yahoo.com.br";
                        String user= "helloween_salvation";
                        String pass= "manuka";             
                        Properties props = new Properties();
                        Authenticator auth = new SMTPAuthenticator();   // autenticador                          
                        Session session = Session.getDefaultInstance(props,auth);
                        session.setDebug(false); // em caso de nao querer debugaçao suprima esta linha                                    
                        Store store = session.getStore("pop3");
                        store.connect(host,user,pass);               
                        Folder folder = store.getFolder("INBOX");
                        folder.open(Folder.READ_ONLY);            
                        Message message[]= folder.getMessages();
                        System.out.println("\nTotal de Mensagens: "+message.length+"\n");                   
                        // Display from (only first) and subject of messages
                        for (int i=0, n=message.length; i<n; i++)
                        {
                                   System.out.println("From:     "+message[i].getFrom()[0]);
                                   System.out.println("Subject:  "+message[i].getSubject());
                                   System.out.println("Mensagem: "+message[i].getContent());
                        }                     
                        folder.close(false);
                        store.close();
            }
}
class SMTPAuthenticator extends Authenticator
{   
            public PasswordAuthentication getPasswordAuthentication()
            {   
                        String username = "helloween_salvation";   
                        String password = "manuka";   
                        return new PasswordAuthentication(username, password);   
            }   
 }


import javax.activation.*;
import javax.mail.internet.*;
import java.util.*;
import javax.mail.*;
public class smtp_anexo
{         
            public static void main(String args[]) throws Exception
            {
                        Properties props = new Properties();
                        props.put("mail.smtp.host", "smtp.mail.yahoo.com.br"); // definicao do host
                        props.put("mail.smtp.auth", "true"); // determina se tera autenticaçao                  
                        Authenticator auth = new SMTPAuthenticator();   // autenticador                          
                        Session s = Session.getInstance(props,auth); 
                        s.setDebug(true); // em caso de nao querer debugaçao suprima esta linha
                        MimeMessage message = new MimeMessage(s);
                        InternetAddress from = new InternetAddress("lilith_nefelin@yahoo.com.br");
                        message.setFrom(from);                       
                        InternetAddress to = new InternetAddress("helloween_salvation@yahoo.com.br");
                        message.addRecipient(Message.RecipientType.TO, to); 
                        message.setSubject("E-Mail enviado a partir do JavaMail.");
                        message.setText("Este é o texto da mensagem enviada através do JavaMail!");                
// Neste ponto entra os Anexos
                        Multipart multiparts = new MimeMultipart();  // Objeto que compoem todas as partes da mensagem
                        BodyPart corpopart = new MimeBodyPart();
                        corpopart.setText("texto");                    
                        multiparts.addBodyPart(corpopart);
                        DataSource DS = new FileDataSource("c:/testes/thread.java");
                        corpopart.setDataHandler(new DataHandler(DS));
                        corpopart.setFileName("thread.java");
                        multiparts.addBodyPart(corpopart);                    
                        message.setContent(multiparts);
                        Transport.send(message);
            }
}
class SMTPAuthenticator extends Authenticator
{   
            public PasswordAuthentication getPasswordAuthentication()
            {   
                        String username = "lilith_nefelin";   
                        String password = "manuka";   
                        return new PasswordAuthentication(username, password);   
            }   
 }


import javax.activation.*;
import javax.mail.internet.*;
import java.util.*;
import javax.mail.*;
public class listdir
{         
            public static void main(String args[]) throws Exception
            {                     
                        String host= "pop.mail.yahoo.com.br";
                        String user= "helloween_salvation";
                        String pass= "manuka"; 
                        Properties props = new Properties();
                        Authenticator auth = new SMTPAuthenticator(user,pass);   // autenticador             
                        Session session = Session.getDefaultInstance(props,auth);
                        session.setDebug(true); // em caso de nao querer debugaçao suprima esta linha              
                        Store store = session.getStore("pop3");
                        store.connect(host,user,pass);                           
                        Folder root         = store.getDefaultFolder();
                        Folder folders[]= root.list();       
                        for (int k=0;k < folders.length;k++)
                        {
                                   Folder tmp = folders[k];
                                   tmp.open(Folder.READ_ONLY);
                                   System.out.println("Nome Completo: "+tmp.getFullName());
                                   System.out.println("Nome: "+tmp.getName());
                                   System.out.println("Qtde: "+tmp.getMessageCount());
                                   System.out.println("Nao lidas: "+tmp.getUnreadMessageCount());
                                   System.out.println("Novas mensagens: "+tmp.getNewMessageCount());
                                   tmp.close(true);
                        }
                        store.close();
            }
}
class SMTPAuthenticator extends Authenticator
{  
            String username;
            String password;           
            public SMTPAuthenticator(String user, String pass){
                        this.username= user;
                        this.password= pass;
            }
            public PasswordAuthentication getPasswordAuthentication()
            {     
                        return new PasswordAuthentication(username, password);   
            }   
 }



import javax.activation.*;
import javax.mail.internet.*;
import java.util.*;
import javax.mail.*;
public class makedir
{         
            public static void main(String args[]) throws Exception
            {                     
                        String host= "pop.mail.yahoo.com.br";
                        String user= "helloween_salvation";
                        String pass= "manuka"; 
                        Properties props = new Properties();
                        Authenticator auth = new SMTPAuthenticator(user,pass);   // autenticador             
                        Session session = Session.getDefaultInstance(props,auth);
                        session.setDebug(true); // em caso de nao querer debugaçao suprima esta linha              
                        Store store = session.getStore("pop3");
                        store.connect(host,user,pass);                                      
                        Folder novo = store.getFolder("teste");
                        if (!novo.exists())
                                   novo.create(Folder.HOLDS_MESSAGES);              
                        store.close();
            }
}


import java.io.*;
import javax.mail.*;
import javax.mail.internet.*;

public class DeleteMessageExample {
  public static void main (String args[]) throws Exception {
    String host = "pop.ig.com.br";
    String username = "torah_1999";
    String password = "manoel";
    Authenticator auth = new SMTPAuthenticator();   // autenticador  
    // Get session
    Session session = Session.getInstance(System.getProperties(), auth);   
    session.setDebug(false);
    // Get the store
    Store store = session.getStore("pop3");
    store.connect(host, username, password);
    // Get folder
    Folder folder = store.getFolder("INBOX");
    folder.open(Folder.READ_WRITE);
    BufferedReader reader = new BufferedReader (
      new InputStreamReader(System.in));
    // Get directory
    Message message[] = folder.getMessages();
    for (int i=0, n=message.length; i<n; i++) {
       System.out.println(message[i].getSubject());
       System.out.println("Do you want to delete message? [YES to delete]");
       String line = reader.readLine();
       // Mark as deleted if appropriate
       if ("YES".equals(line)) {
         message[i].setFlag(Flags.Flag.DELETED, true);
       }
    }
    // Close connection
    folder.close(true);
    store.close();
  }
}
class SMTPAuthenticator extends Authenticator
{   
            public PasswordAuthentication getPasswordAuthentication()
            {   
                        String username = "torah_1999";   
                        String password = "manoel";   
                        return new PasswordAuthentication(username, password);   
            }   
 }


Recebe mensagens
 
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.Security;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.*;
import javax.mail.internet.InternetAddress;

public class RecebeMail {
  
    public static void main(String args[]) throws Exception {
      
        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
      
        new RecebeMail().recebeMSG();
    }
    public void recebeMSG() throws MessagingException {
              
        Properties props = new Properties();
        props.put("mail.pop3.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.put("mail.pop3.socketFactory.fallback", "false");
        props.put("mail.store.protocol", "pop3");
  
        Session session = Session.getDefaultInstance(props,null);
        Store store = session.getStore("pop3");
      
        //Estabelece conexão
        store.connect("pop.gmail.com",995, "USUARIO", "SENHA");
      
        //Obtem a pasta e a abre
        Folder folder = store.getFolder("INBOX");
        folder.open(Folder.READ_ONLY);
      
        //Obtem mensagens
        Message msg[] = folder.getMessages();
      
        for (int i = 0; i < msg.length; i++){
            try {
                System.out.println("MENSAGEM:" + i);
                System.out.println("NOME: " + ((InternetAddress) msg[i].getFrom()[0]).getPersonal() + "\n" +
                                   "FROM: " + ((InternetAddress) msg[i].getFrom()[0]).getAddress());
                System.out.println("DATA DE ENVIO: " + msg[i].getSentDate());
                System.out.println("ASSUNTO "+msg[i].getSubject());
                System.out.println("CONTEUDO " +msg[i].getContent());
                System.out.println("FIM DA MENSAGEM: " + i);
            } catch (MessagingException ex) {
                ex.printStackTrace();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
              
        folder.close(false);
        store.close();
    }

}