volatile позволяет разным потокам видеть "актуальное" значение переменной,потому что любые изменения сразу же записываются в память, в то время как если не объявлять переменную с этим ключевым словом - её значение может сохраняться в кеше.
Статическая переменная - переменная, которая инициализируется при первом вызове класса и значение её одинаково для всех экземпляров класса.
Когда применять те или иные ?
Ну первую ,что очевидно,при работе с примитивными типами из нескольких потоков (к примеру 2 потока обращаются к переменной-счетчику)
а static же ...Ну тут много разных вариантов