2016-10-20 3 views
0

У меня есть следующий класс:Как проверить, если статический метод потокобезопасен

public class MyTestThreadStatic { 

    private static int myNum; 

     private MyTestThreadStatic() { // private constructor 
     } 
     public static void setMyNum(int val) { 
      myNum = val; 
     } 
     public static int addOne() { 
      return myNum + 1; 
     } 

.....

code block { 
//thread 1 at t0 
... some code to create a thread to call static class 
System.out.println("val=" + MyTestThreadStatic.addOne()); 
... some other code to create a thread to call static class 
//thread 2 at t0 
MyTestThreadStatic.setMyNum(200); 
System.out.println("val=" + MyTestThreadStatic.addOne()); 
} 

     //stack created? 

В t0 (время 0), два потока вызова функции аддоне. Будет ли это работать так, как ожидалось? Будет ли это работать, потому что были созданы два стека? Я бы хотел проверить это и посмотреть на Thread и Runnable, но я не вижу пути, поскольку у меня нет статических методов и требуется экземпляр объекта.

+1

Вы понимаете, что здесь у вас нет двух потоков, верно? –

+1

Вы понимаете, что 'addOne()' не увеличивает значение, оно просто добавляет 1 к тому, что вы в последний раз устанавливали. например если вы вызовете 100 раз, он будет возвращать одинаковое значение каждый раз. –

+0

Да. Пробовал создавать потоки, но не мог понять. – paulj

ответ

1

Вам не нужно проверять это; это очевидно что это нет нить надежный. Когда есть общая информация, и эта информация читается/записывается параллельно, вам нужен способ защиты.

Что нет в вашем коде. Таким образом: как только у вас есть несколько потоков, «работающих» с этим счетчиком способами, которые могут привести к разным результатам в разных сценариях, все ставки отключены.

Если ваш вопрос: как я могу написать программу, которая показывает поточные вопросы, вы можете сделать что-то вроде:

  1. Создайте метод, который считывает, что INT значения, а затем увеличивает его на 1
  2. Создать n темы; и каждый из них просто вызывает метод м раз

Теперь можно было бы ожидать, что окончательное значение счетчика должно быть п х м. Но вы должны быстро найти, что счетчик будет не иметь то точное значение в конце!

Если вы хотите «увидеть» такие эффекты с помощью двух методов, которые вы создали, вам понадобится что-то вроде этого (пример псевдокода)!

public void loopUntilMismatch() { 
    while (true) { 
    int value = random number 
    setMyNum(value); 
    int increasedValue = addOne(); 
    if (increasedValue != value + 1) { 
     print "fail ... 
     exit 
    } 
    } 

При выполнении этого метода с использованием нескольких потоков, это не займет много времени, пока не смочь распечатываются и ваша программа завершается.

+0

BTW 'addOne()' не является 'return myNum ++;', что я и предполагал. –

+0

Да. Это то, что я искал. – paulj

+0

@paulj Рад это слышать. Если да, подумайте о принятии моих ответов - я думаю, вы больше не получите никаких других. – GhostCat

1

Это не потолочный сейф, и он не пытается быть.

Тест не может доказать, что код является потокобезопасным. Он может только попытаться доказать, что он не является потокобезопасным.

Чтобы доказать, что это не поточно вам просто нужно переставить строки кода, как этот

System.out.println("val=" + MyTestThreadStatic.addOne()); // Thread 1 

MyTestThreadStatic.setMyNum(200); // thread 2 
System.out.println("val=" + MyTestThreadStatic.addOne()); // thread 2 

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

MyTestThreadStatic.setMyNum(200); // thread 2 
System.out.println("val=" + MyTestThreadStatic.addOne()); // Thread 1 
System.out.println("val=" + MyTestThreadStatic.addOne()); // thread 2 

Теперь оба потока печатают одно и то же.

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

+0

@GhostCat да, я был в середине изменения линии и получил ti испорчен. ;) –

+1

Одна из причин этого заключается в том, что «безопасность потоков» - это не вещь, это отсутствие вещи или даже несколько вещей (условия гонки, взаимоблокировки и т. Д.). Не говоря уже о том, что в более широком смысле безопасность потоков зависит от того, что вы ожидаете от кода. Поэтому в этом отношении иногда даже анализа самого кода недостаточно. – biziclop

+0

@biziclop согласился. StringBuffer, по сути, является потокобезопасным, но практически невозможно использовать в потоковом режиме без дополнительной блокировки. –

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