2015-02-04 3 views
3

Хотите знать разницу между ниже двух кодов
Мой первый кодВ чем разница между двумя многопоточными java-кодами?

package com.app.myclasses; 

class RunnableTest implements Runnable { 
    @Override 
    public void run() { 
     // TODO Auto-generated method stub 

     for (int i = 0; i < 5; i++) { 
      System.out.println(i); 
     } 
    } 
} 
public class ThreadTesting { 
    public static void main(String[] args) { 
     RunnableTest r1 = new RunnableTest(); 
     Thread t1 = new Thread(r1, "first"); 
     t1.start(); 
     Thread t2 = new Thread(r1, "second"); 
     t2.start(); 
    } 
} 

В коде выше я создал две нити, используя только один работоспособный экземпляр
Теперь посмотрим на код ниже

package com.app.myclasses; 
class RunnableTest implements Runnable { 
    @Override 
    public void run() { 
     // TODO Auto-generated method stub 

     for (int i = 0; i < 5; i++) { 
      System.out.println(i); 
     } 
    } 
} 
public class ThreadTesting { 
    public static void main(String[] args) { 
     RunnableTest r1 = new RunnableTest(); 
     RunnableTest r2 = new RunnableTest(); 
     Thread t1 = new Thread(r1, "first"); 
     t1.start(); 
     Thread t2 = new Thread(r2, "second"); 
     t2.start(); 
    } 
} 

Во втором коде я создал два исполняемых экземпляра r1 и r2 и соответственно созданные потоки

Итак, wh at - разница в выше двух кодах? Есть ли проблема с использованием памяти или проблема с производительностью, или один из них не является многопоточным?

+0

Там нет никакой разницы. «RunnableTest» не имеет состояния. – xehpuk

ответ

0

В первом примере у вас есть один экземпляр RunnableTest, и поэтому любые переменные экземпляра будут совместно использоваться двумя потоками. Во втором случае есть два экземпляра, поэтому потоки будут передавать только статические данные.

например

class RunnableTest implements Runnable { 
    static String shared = "Shared static data"; 
    String instance = "Instance data"; 
    @Override 
    public void run() { 
     // TODO Auto-generated method stub 

     System.out.println(Thread.currentThread().getName() + " " + shared + " " + instance); 
    } 
    RunnableTest(String instance) { 
     this.instance = instance; 
    } 
    public static void main(String[] args) { 
     RunnableTest r1 = new RunnableTest("instance1"); 
     Thread t1 = new Thread(r1, "first"); 
     t1.start(); 
     Thread t2 = new Thread(r1, "second"); 
     t2.start(); 
    } 
} 

дает

first Shared static data instance1 
second Shared static data instance1 

в то время как

class RunnableTest implements Runnable { 
    static String shared = "Shared static data"; 
    String instance = "Instance data"; 
    @Override 
    public void run() { 
     // TODO Auto-generated method stub 

     System.out.println(Thread.currentThread().getName() + " " + shared + " " + instance); 
    } 
    RunnableTest(String instance) { 
     this.instance = instance; 
    } 
    public static void main(String[] args) { 
     RunnableTest r1 = new RunnableTest("instance1"); 
     Thread t1 = new Thread(r1, "first"); 
     t1.start(); 
     Thread t2 = new Thread(r1, "second"); 
     t2.start(); 
    } 
} 

дает

first Shared static data instance1 
second Shared static data instance2 
6

Метод локальных переменных: неявно поточно-безопасный. Таким образом, не имеет значения в ваш случай с i is не общий.

Рассмотрим такой случай:

class RunnableTest implements Runnable { 

int i = 0; 

@Override 
public void run() { 
    // TODO Auto-generated method stub 

    for (i = 0; i < 5; i++) { 
     System.out.println(Thread.currentThread().getName() + " : " + i); 
    } 
} 

}

Теперь

class ThreadTesting { 
    public static void main(String[] args) { 
     RunnableTest r1 = new RunnableTest(); 
     Thread t1 = new Thread(r1, "first"); 
     t1.start(); 
     Thread t2 = new Thread(r1, "second"); 
     t2.start(); 
    } 
} 

Приведенный выше код не даст вам правильный вывод (0-4 дважды). Вывод будет что-то вроде:

first : 0 
second : 0 
first : 1 
second : 2 
first : 3 
second : 4 

Мы уровня экземпляра поля (которые являются общими) здесь. Таким образом, результат не является тем, что вы ожидаете.

В другом случае поля уровня не разделены между потоками. Поскольку у вас есть 2 разных runnables.

Если вы хотите синхронизировать внутри работоспособный экземпляр и если вы используете this, то работает только на one instance будет правильным вместо 2 seperate runnable instances. Примечание: Блокировка на runnable экземпляр считается плохим дизайном.

Смежные вопросы