Como dividir as tarefas de um método para ser executada por diferentes threads

É o seguinte, estou implementado um Web Crawler utilizando threads, mas ele não está dividindo as tarefas entre as threads, quando eu chamo a Thread t2 ela realiza exatamente a mesma coisa que a Thread t1 está fazendo, eu preciso que elas dividam a tarefa, enquanto t1 estiver fazendo uma coisa, preciso que t2 faça outra.

Queria uma maneira que por exemplo, enquanto t1 verifica o site “a”, t2 verifica o site “b”, mas tudo que fazem é repetir exatamente a mesma operação.

Código:

import java.lang.Thread;
import java.lang.Runnable;

import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.Queue;
import java.util.LinkedList;
import java.util.Set;
import java.util.HashSet;
import java.net.*;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class crawlerBackup extends Thread {
           // initial web page
        String s = "http://videira.ifc.edu.br/";
        int i=0;
        int j=0;
        int k=0;
        int cont=0; 
        int a = 0;
        int aux=0;
        
    public  void run () {
     
    // timeout connection after 500 miliseconds
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout",    "10000");
		
  // list of web pages to be examined
        Queue<String> q = new LinkedList<String>();
        q.add(s);
		
        // existence symbol table of examined web pages
        Set<String> set = new HashSet<String>();
        set.add(s);
        
         // breadth first search crawl of web
         while (!q.isEmpty()) {
           
 if (i == 1 || i == a){
             a=j;
             cont++;
             }
             
             if (cont <= 3){
             
       // System.out.println("\nvalor do contador: " + cont);
             
          // System.out.println("\nvalor do a: " + a + "\n");
            i++;
            k=0;
                  
         String v = q.remove();
          System.out.println(i + " " + getName());
            System.out.println(i + ": " + "URL inicial: " + v + "\n");
			
            //salva a hora corrente em milisegundos
			long inicio = System.currentTimeMillis(); 
		try {
                 
			URL url = new URL(v);
			URLConnection conexao = url.openConnection();
			BufferedReader in = 
				new BufferedReader(
					new InputStreamReader(conexao.getInputStream()));
			
            String input = "";
			String inputLine;
			while ((inputLine = in.readLine()) != null) 
				input = input + inputLine;
			in.close();
			
			/*************************************************************
			 *  Find links of the form: http://xxx.yyy.zzz
			 *  \\w+ for one or more alpha-numeric characters
			 *  \\. for dot
			 *  could take first two statements out of loop
			 *************************************************************/
            String  regexp  = "http://(\\w+\\.)*(\\w+)";
            Pattern pattern = Pattern.compile(regexp);
            Matcher matcher = pattern.matcher(input);
			
            // find and print all matches
 while (matcher.find()) {

            String w = matcher.group();
                if (!set.contains(w)) {
                  
                   k++;
                    j++;
                    q.add(w);
                    set.add(w);
                    set.add(w);
                    
System.out.println("Total encontrado no site: " + k + " | " + " total de sites encontrados: " + j + " Endereço: " + w);
                    }
                }
           //calcula o tempo de processamento em millisegundos 
	
		for (String sUrl : q) {
                    
                    k++;
                    j++;
System.out.println("Total encontrado no site: "+ k + " | " + "total de sites encontrados: " + j + " Endereço: " + sUrl);
                }
                
                long tempoGasto = System.currentTimeMillis() - inicio;
         
		System.out.println("\nTempo de processamento: " + tempoGasto/1000f + " segundos\n");
                
                
         } 
             catch(UnknownHostException ex) {
              System.out.println("\n\n erro: " + ex +"\n\n");
        
                 }
        
        catch(IOException ex) {
              System.out.println("\n\n erro: " + ex +"\n\n");
        
                 } 
             } else {
             System.exit(0);
             }
             }
       
    }

public static void main(String[] args){ 

    
    crawlerBackup newcrawler = new crawlerBackup() ;
    crawlerBackup newcrawler2 = new crawlerBackup() ;


     Thread t1 = new Thread(newcrawler);
    Thread t2 = new Thread(newcrawler2);
 
     t1.start();
    t2.start();
  }
}

eles estão fazendo a mesma coisa porque você esta pedindo que eles façam isso, se você quer que eles façam coisas diferentes você tem que passar dois objetos diferentes, para poder existir dois metodos run() diferentes.
o nome da thread pode ser diferente e o objeto que cada thread esta usando é “diferente”, mas do que adianta tudo isso ser diferente se você esta usando o mesmo metodo run() nas duas thread ?

se você quer que a Thread t1 faça uma coisa e a t2 outra vc tem q mudar os objetos e o codigo de cada metodo run().Exemplo:

SiteA newcrawler = new SiteA() ;
SiteB newcrawler2 = new SiteB() ;
 Thread t1 = new Thread(newcrawler);
Thread t2 = new Thread(newcrawler2);

 t1.start();
t2.start();

desse jeito eles são diferentes e cada um vai ter o seu método run() e cada metodo run() vai fazer algo diferente.

Johny, se tu colocar o código todo dentro da Thread ele vai abrir ela e executar dentro daquela thread todo o processamento. O que tu pode fazer é colocar a parte que você quer que rode concorrentemente em threads diferentes e passar para essa thread um conjunto de dados diferente, por exemplo, um thread processa a url X e outra a Y.
Acredito que com os links que te passei por e-mail tu consiga fazer isso.

Complementando a resposta, tu pode usar o mesmo código no crawler, porém passando objetos diferentes para ele processar, ou URL diferente como parâmetro. Você pode delimitar uma range de valores dentro da lista que está guardando as URLs e explorar apenas uma parte dela em cada thread.