2015-11-11 2 views
0

Я пробую коды с несколькими потоками. Ниже мой код:Печать номеров в петлях с двумя потоками

package com.thread.practice; 

public class ThreadPratice1 { 

    public static void main(String[] args) { 
     MyRunnable r = new MyRunnable(); 
     Thread t1 = new Thread(r, "Thread 1"); 
     Thread t2 = new Thread(r, "Thread 2"); 
     t1.start(); 
     t2.start(); 
    } 
} 

package com.thread.practice; 

public class MyRunnable implements Runnable { 
    private static int i = 0; 
    @Override 
    public void run() { 
     for(i = 0; i <10;i++){ 
      System.out.println("Thread: "+ Thread.currentThread().getName() 
        +" value of i: "+i); 
      try { 
       //System.out.println("Thread: "+ i); 
       Thread.sleep(1000); 
       //System.out.println("inside runnable: "+Thread.currentThread().getState()); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

Но на выходе она всегда выдавались значение I как 0 дважды в начале.

Выход приходит вроде этого:

Thread: Thread 1 value of i: 0 
Thread: Thread 2 value of i: 0 
Thread: Thread 1 value of i: 2 
Thread: Thread 2 value of i: 2 
Thread: Thread 1 value of i: 3 
Thread: Thread 2 value of i: 4 
Thread: Thread 1 value of i: 5 
Thread: Thread 2 value of i: 6 
Thread: Thread 1 value of i: 7 
Thread: Thread 2 value of i: 8 
Thread: Thread 1 value of i: 9 

Может кто-то пожалуйста, помогите мне понять этот вопрос?

+1

Каждый инициируемый вами поток инициализирует 'i' обратно' 0' в цикле 'for' – BeyelerStudios

ответ

2

Поскольку значение i при прохождении двух потоков составляет 0.

Другими словами, нить одна и нить два смотрели почти в одно и то же время, поэтому оба из них устанавливают i на 0 для первого цикла.

for(i = 0; i <10;i++) { 

Тогда значение изменяется между нитью, потому что вы сделали i статичным. поэтому он будет разделен между вашими двумя потоками.

+0

Ok. Но когда первый поток будет выполнен, он не должен увеличивать значение до 1. Таким образом, когда второй поток получает шанс, не должен ли он печатать 1? –

+0

Нет, он не увеличит значение до 1 при первом вводе, так как вы снова инициализируете 'i', говоря' for (i = 0; i <10; i ++) {' – Salah

2

Вы сделали статическую «i», что означает, что она будет одинаковой для всех потоков и объектов. Уберите статический модификатор, и ваш код будет работать правильно.

редактировать: Я неправильно истолкованы, что вы asked- не ставим я к 0 в течение цикла, это будет выглядеть примерно так:

for(;i<10;i++) { /*mycode*/} 

Один из этих двух, вероятно, что вы хотите, в любом случае, ваш вопрос был немного расплывчатым

0

Значение i сгенерировано циклом for только после выполнения цикла. Выполнение цикла for занимает конечное время. Поскольку вы запускаете потоки вместе (почти), оба потока могут или не могут печатать i после того, как другой поток завершил один цикл. Поскольку вы не делаете для обеспечения безопасности потоков, результат будет непредсказуемым, как тот, который вы получили.

0

Во-первых, Вы не должны использовать примитивный тип INT параллелизма, это не поточно, и это, возможно, приведет к Race Condition,

и попытаться использовать AtomicInteger заменить int, это поточно. например, может быть:

public class ThreadPratice1 { 

    public static void main(String[] args) { 
     AtomicInteger number = new AtomicInteger(0); 
     MyRunnable r = new MyRunnable(number); 
     Thread t1 = new Thread(r, "Thread 1"); 
     Thread t2 = new Thread(r, "Thread 2"); 
     t1.start(); 
     t2.start(); 
    } 
} 

class MyRunnable implements Runnable { 
    private AtomicInteger number; 

    public MyRunnable(AtomicInteger number) { 
     this.number = number; 
    } 

    @Override 
    public void run() { 
     while (number.get() < 10) { 
      System.out.println("Thread: " + Thread.currentThread().getName() 
        + " value of i: " + number.getAndIncrement()); 
     } 
    } 
} 
Смежные вопросы