Como posso passar um parâmetro para um segmento Java?

Alguém pode me sugerir como posso passar um parâmetro para um segmento?

Além disso, como funciona para classs anônimas?

Você precisa passar o parâmetro no construtor para o object Runnable:

public class MyRunnable implements Runnable { public MyRunnable(Object parameter) { // store parameter for later user } public void run() { } } 

e invoque-o assim:

 Runnable r = new MyRunnable(param_value); new Thread(r).start(); 

Para classs anônimas:

Em resposta às edições de perguntas, aqui está como funciona para as classs Anônimas

  final X parameter = ...; // the final is important Thread t = new Thread(new Runnable() { p = parameter; public void run() { ... }; t.start(); 

Classes nomeadas:

Você tem uma class que estende Thread (ou implementa Runnable) e um construtor com os parâmetros que você gostaria de passar. Em seguida, quando você cria o novo segmento, você tem que passar os argumentos e, em seguida, inicie o segmento, algo como isto:

 Thread t = new MyThread(args...); t.start(); 

Runnable é uma solução muito melhor que o Thread BTW. Então eu prefiro:

  public class MyRunnable implements Runnable { private X parameter; public MyRunnable(X parameter) { this.parameter = parameter; } public void run() { } } Thread t = new Thread(new MyRunnable(parameter)); t.start(); 

Esta resposta é basicamente a mesma que esta pergunta semelhante: Como passar parâmetros para um object Thread

via construtor de uma class Runnable ou Thread

 class MyThread extends Thread { private String to; public MyThread(String to) { this.to = to; } @Override public void run() { System.out.println("hello " + to); } } public static void main(String[] args) { new MyThread("world!").start(); } 

Quando você cria um thread, você precisa de uma instância de Runnable . A maneira mais fácil de passar um parâmetro seria passá-lo como um argumento para o construtor:

 public class MyRunnable implements Runnable { private volatile String myParam; public MyRunnable(String myParam){ this.myParam = myParam; ... } public void run(){ // do something with myParam here ... } } MyRunnable myRunnable = new myRunnable("Hello World"); new Thread(myRunnable).start(); 

Se você quiser alterar o parâmetro enquanto o encadeamento estiver em execução, basta adicionar um método setter à sua class executável:

 public void setMyParam(String value){ this.myParam = value; } 

Depois de ter isso, você pode alterar o valor do parâmetro chamando assim:

 myRunnable.setMyParam("Goodbye World"); 

Claro, se você quiser acionar uma ação quando o parâmetro for alterado, você terá que usar bloqueios, o que torna as coisas consideravelmente mais complexas.

Essa resposta chega muito tarde, mas talvez alguém ache útil. É sobre como passar um parâmetro (s) para um Runnable sem declarar a class nomeada (útil para inliners):

 String someValue = "Just a demo, really..."; new Thread(new Runnable() { private String myParam; public Runnable init(String myParam) { this.myParam = myParam; return this; } @Override public void run() { System.out.println("This is called from another thread."); System.out.println(this.myParam); } }.init(someValue)).start(); 

Claro que você pode adiar a execução do start para algum momento mais conveniente ou apropriado. E cabe a você o que será a assinatura do método init (por isso, pode levar mais e / ou argumentos diferentes) e, claro, até mesmo o seu nome, mas basicamente você tem uma idéia.

Na verdade, há também outra maneira de passar um parâmetro para uma class anônima, com o uso dos blocos inicializadores. Considere isto:

 String someValue = "Another demo, no serious thing..."; int anotherValue = 42; new Thread(new Runnable() { private String myParam; private int myOtherParam; { this.myParam = someValue; this.myOtherParam = anotherValue; } @Override public void run() { System.out.println("This comes from another thread."); System.out.println(this.myParam + ", " + this.myOtherParam); } }).start(); 

Então tudo acontece dentro do bloco inicializador.

Para criar um segmento, você normalmente cria sua própria implementação de Runnable. Passe os parâmetros para o encadeamento no construtor desta class.

 class MyThread implements Runnable{ private int a; private String b; private double c; public MyThread(int a, String b, double c){ this.a = a; this.b = b; this.c = c; } public void run(){ doSomething(a, b, c); } } 

Você pode estender a class Thread ou a class Runnable e fornecer os parâmetros desejados. Existem exemplos simples nos documentos . Eu vou portá-los aqui:

  class PrimeThread extends Thread { long minPrime; PrimeThread(long minPrime) { this.minPrime = minPrime; } public void run() { // compute primes larger than minPrime . . . } } PrimeThread p = new PrimeThread(143); p.start(); class PrimeRun implements Runnable { long minPrime; PrimeRun(long minPrime) { this.minPrime = minPrime; } public void run() { // compute primes larger than minPrime . . . } } PrimeRun p = new PrimeRun(143); new Thread(p).start(); 

Escreva uma class que implemente Runnable e passe o que você precisa em um construtor adequadamente definido, ou escreva uma class que estenda Thread com um construtor adequadamente definido que chame super () com os parâmetros apropriados.

Você pode derivar uma class de Runnable e durante a construção (digamos) passar o parâmetro para dentro.

Em seguida, inicie-o usando Thread.start (Runnable r);

Se você quer dizer enquanto o thread está rodando, então simplesmente segure uma referência ao seu object derivado no thread de chamada, e chame os methods setter apropriados (sincronizando onde apropriado)

Parâmetro que passa pelos methods start () e run ():

 // Tester public static void main(String... args) throws Exception { ThreadType2 t = new ThreadType2(new RunnableType2(){ public void run(Object object) { System.out.println("Parameter="+object); }}); t.start("the parameter"); } // New class 1 of 2 public class ThreadType2 { final private Thread thread; private Object objectIn = null; ThreadType2(final RunnableType2 runnableType2) { thread = new Thread(new Runnable() { public void run() { runnableType2.run(objectIn); }}); } public void start(final Object object) { this.objectIn = object; thread.start(); } // If you want to do things like setDaemon(true); public Thread getThread() { return thread; } } // New class 2 of 2 public interface RunnableType2 { public void run(Object object); } 

A partir do Java 8, você pode usar um lambda para capturar parâmetros efetivamente finais . Por exemplo:

 final String param1 = "First param"; final int param2 = 2; new Thread(() -> { // Do whatever you want here: param1 and param2 are in-scope! System.out.println(param1); System.out.println(param2); }).start(); 

Existe uma maneira simples de passar parâmetros para runnables. Código:

 public void Function(final type variable) { Runnable runnable = new Runnable() { public void run() { //Code adding here... } }; new Thread(runnable).start(); } 

No Java 8, você pode usar expressões lambda com a API de simultaneidade e o ExecutorService como uma substituição de nível superior para trabalhar diretamente com encadeamentos:

newCachedThreadPool() Cria um conjunto de encadeamentos que cria novos encadeamentos conforme necessário, mas reutiliza encadeamentos criados anteriormente quando eles estão disponíveis. Esses pools normalmente melhoram o desempenho de programas que executam muitas tarefas assíncronas de curta duração.

  private static final ExecutorService executor = Executors.newCachedThreadPool(); executor.submit(() -> { myFunction(myParam1, myParam2); }); 

Veja também executors javadocs .

Mais uma opção; essa abordagem permite usar o item Runnable como uma chamada de function assíncrona. Se a sua tarefa não precisa retornar um resultado, por exemplo, ela apenas realiza alguma ação que você não precisa se preocupar sobre como você repassa um “resultado”.

Esse padrão permite reutilizar um item, onde você precisa de algum tipo de estado interno. Quando não está passando o (s) parâmetro (s) no construtor, é necessário ter cuidado para mediar o access dos programas aos parâmetros. Você pode precisar de mais verificações se o seu caso de uso envolver diferentes chamadores, etc.

 public class MyRunnable implements Runnable { private final Boolean PARAMETER_LOCK = false; private X parameter; public MyRunnable(X parameter) { this.parameter = parameter; } public void setParameter( final X newParameter ){ boolean done = false; synchronize( PARAMETER_LOCK ) { if( null == parameter ) { parameter = newParameter; done = true; } } if( ! done ) { throw new RuntimeException("MyRunnable - Parameter not cleared." ); } } public void clearParameter(){ synchronize( PARAMETER_LOCK ) { parameter = null; } } public void run() { X localParameter; synchronize( PARAMETER_LOCK ) { localParameter = parameter; } if( null != localParameter ) { clearParameter(); //-- could clear now, or later, or not at all ... doSomeStuff( localParameter ); } } 

}

Thread t = new Thread (new MyRunnable (parâmetro)); t.start ();

Se você precisar de um resultado de processamento, também precisará coordenar a conclusão do MyRunnable quando a subtarefa terminar. Você poderia passar uma chamada de volta ou apenas esperar no Thread ‘t’, etc.

Especialmente para Android

Para fins de retorno de chamada, eu geralmente implemento meu próprio Runnable genérico com parâmetro (s) de input:

 public interface Runnable { void run(TResult result); } 

O uso é simples:

 myManager.doCallbackOperation(new Runnable() { @Override public void run(MyResult result) { // do something with the result } }); 

No gerente:

 public void doCallbackOperation(Runnable runnable) { new AsyncTask() { @Override protected MyResult doInBackground(Void... params) { // do background operation return new MyResult(); // return resulting object } @Override protected void onPostExecute(MyResult result) { // execute runnable passing the result when operation has finished runnable.run(result); } }.execute(); } 

Não, você não pode passar parâmetros para o método run() . A assinatura informa que (não possui parâmetros). Provavelmente, a maneira mais fácil de fazer isso seria usar um object construído propositadamente que usa um parâmetro no construtor e o armazena em uma variável final:

 public class WorkingTask implements Runnable { private final Object toWorkWith; public WorkingTask(Object workOnMe) { toWorkWith = workOnMe; } public void run() { //do work } } //... Thread t = new Thread(new WorkingTask(theData)); t.start(); 

Depois de fazer isso, é preciso ter cuidado com a integridade dos dados do object que você passa para a ‘WorkingTask’. Os dados agora existirão em dois segmentos diferentes, portanto, você precisa se certificar de que é Segmentação Segura.