2015-08-12 7 views
0

У меня есть этот код.Как использовать синхронизированный метод?

public class Main{ 

    public static void main(String[] args) { 
    Main1 main1 = new Main1(); 
    Main2 main2 = new Main2(); 
    Thread t1 = new Thread(main1); 
    Thread t2 = new Thread(main2); 
    t1.start(); 
    t2.start(); 
    } 
} 
public class Main1 extends Thread{ 
    SynchronizedCounter c = new SynchronizedCounter(); 
    public void run(){ 
     System.out.println("Entering Main1"); 
     c.print(); 
     System.out.println("Exiting Main1"); 
    } 
} 
public class Main2 extends Thread{ 
    SynchronizedCounter c = new SynchronizedCounter(); 
    public void run(){ 
     System.out.println("Entering Main2"); 
     c.print(); 
     System.out.println("Exiting Main2"); 
    } 
} 
public class SynchronizedCounter { 
    public void print() { 
     for(int i = 1; i<10; i++){ 
      System.out.print(i+ " "); 
     } 
    } 
} 

Когда я запускаю этот код, у меня получается другой вывод, который я понимаю, почему. Чтобы синхронизировать его, я добавил синхронизованное ключевое слово для print() в класс SynchronizedCounter. Теперь это выглядит так.

public class SynchronizedCounter { 
public synchronized void print() { 
    for(int i = 1; i<10; i++){ 
     System.out.print(i+ " "); 
    } 
    } 
} 

Но, все же, когда я запускаю его, я получаю случайный результат. Я не уверен, как сделать его синхронизированным, сделав метод синхронизированным, так что он дает фиксированный результат.

, например:

Entering Main1 
1 2 3 4 5 6 7 8 9 
Exiting Main1 
Entering Main2 
1 2 3 4 5 6 7 8 9 
Exiting Main2 

Edit: Спасибо Kayaman за ответ. Сейчас он работает нормально. Я немного изменил код. Теперь это выглядит так.

public class Main{ 

public static void main(String[] args) { 
    SynchronizedCounter c = new SynchronizedCounter(); 
    Main1 main1 = new Main1(c); 
    Main2 main2 = new Main2(c); 
    Thread t1 = new Thread(main1); 
    Thread t2 = new Thread(main2); 
    t1.start(); 
    t2.start(); 
} 
} 

public class Main1 extends Thread{ 
SynchronizedCounter c; 
Main1(SynchronizedCounter counter){ 
    c = counter; 
} 
public void run(){ 
    c.print(); 
} 
} 

public class Main2 extends Thread{ 
SynchronizedCounter c; 
Main2(SynchronizedCounter counter){ 
    c = counter; 
} 
public void run(){ 
    c.print(); 
} 
} 

public class SynchronizedCounter { 
public static int i = 0; 
public synchronized void print() { 
    System.out.println("\n Thread "+ i); 
    i++; 
    for(int i = 1; i<10; i++){ 
     System.out.print(i+ " "); 
    } 
} 
} 

Теперь, выход пришествие:

Thread 0 
1 2 3 4 5 6 7 8 9 
Thread 1 
1 2 3 4 5 6 7 8 9 
+0

Я запутался , Что вы пытаетесь проверить. Что такое текущий выход? Здесь нет места для синхронизации. –

+0

В чем именно проблема, которую вы пытаетесь решить? На данный момент у вас есть потоки, которые пишут 1-9 на консоли. Поскольку оба одновременно записываются на одну и ту же консоль, вывод получается довольно случайным. –

+0

@FlorianSchaetz Я предполагаю, что это всего лишь опыт обучения. Фактически, если синхронизация работает, он должен получить 1-10 в два раза подряд вместо смешаемых чисел - я думаю, это то, что он ожидает. – Thomas

ответ

7

Нити должны использовать один и тот же экземпляр SynchronizedCounter для синхронизации работы. Поскольку у вас есть 2 экземпляра кода, оба потока будут синхронизироваться в своем собственном экземпляре, а не в блоке.

0

Как уже указывалось другими, установка synchronized на методы синхронизируется с экземпляром класса, и поскольку у вас есть 2, вы фактически не синхронизируете оба потока.

Поэтому в зависимости от ваших потребностей, либо

  • использует один и тот же экземпляр SynchronizedCounter в обеих нитях, или
  • положить синхронизированный блок внутри методы (вокруг тела) и синхронизировать на классе, т.е. synchronized(SynchronizedCounter.class) { ... }

Edit:

журнал связи на ваш ожидаемый результат: поскольку вы не синхронизируете методы run() ваших потоков, там содержатся инструкции печати. System.out.println("Entering Main1"); все равно может быть смешано, то есть даже счетчик быть правильно синхронизированы, вы все еще могли бы получить что-то вроде этого (кстати там нет LINEBREAK после печати номера, я полагаю, вы добавите его):

Entering Main2 
Entering Main1 
1 2 3 4 5 6 7 8 9 
Exiting Main2 
1 2 3 4 5 6 7 8 9 
Exiting Main1 
Смежные вопросы