with open('file') as f :
numbers = f.readlines()
last_nums = [ line.split()[-1] for line in numbers ]
line.split()
разделит строку на элементы списка, используя пробел в качестве разделителя (если вы не поместите в него аргументы), [-1]
получит для вас последний элемент этого списка
Это зависит от того, хотите ли Вы, чтобы Ваш класс был ориентирован на многопотоковое исполнение. Большинство классов не должно быть ориентировано на многопотоковое исполнение (для простоты), в этом случае, Вам не нужна синхронизация. При необходимости в нем, чтобы быть ориентированными на многопотоковое исполнение, необходимо синхронизировать доступ , или делают переменную энергозависимой. (Это избегает других потоков, получающих "устаревшие" данные.)
synchronized
модификатор действительно плох идея и должен избежаться любой ценой. Я думаю, что это похвально, которого Sun пытался сделать блокировку немного легче достигнуть, но synchronized
правые дела больше проблемы, чем он стоит.
проблема - то, что synchronized
метод является на самом деле просто сахаром синтаксиса для получения блокировки на this
и содержание его на время метода. Таким образом, public synchronized void setInstanceVar()
было бы эквивалентно чему-то вроде этого:
public void setInstanceVar() {
synchronized(this) {
instanceVar++;
}
}
Это плохо по двум причинам:
synchronized
методы в том же классе используют ту же самую блокировку, которая уменьшает пропускную способность нет ничего, чтобы препятствовать тому, чтобы я делал что-то вроде этого в другом классе:
MyClass c = new MyClass();
synchronized(c) {
...
}
В том synchronized
блок, я держу блокировку, которая требуется всем synchronized
методы в [1 111]. Это далее уменьшает пропускную способность и существенно увеличения возможности мертвой блокировки.
А лучший подход должен иметь специализированное lock
объект и использовать synchronized(...)
блок непосредственно:
public class MyClass {
private int instanceVar;
private final Object lock = new Object(); // must be final!
public void setInstanceVar() {
synchronized(lock) {
instanceVar++;
}
}
}
, С другой стороны, можно использовать эти java.util.concurrent.Lock
интерфейс и java.util.concurrent.locks.ReentrantLock
реализация для достижения в основном того же результата (на самом деле, это - то же на Java 6).
Если бы Вы хотите сделать этот класс ориентированным на многопотоковое исполнение, я объявил бы instanceVar
как volatile
удостоверяться, что Вы всегда получаете наиболее обновленное значение из памяти, и также я сделал бы setInstanceVar()
synchronized
, потому что в JVM инкремент не является атомарной операцией.
private volatile int instanceVar =0;
public synchronized setInstanceVar() { instanceVar++;
}
. Примерно, ответ, "он зависит". Синхронизация Вашего метода set и метода считывания здесь только имела бы намеченную цель гарантировать, что несколько потоков не могли считать переменные между каждым, другие увеличивают операции:
synchronized increment()
{
i++
}
synchronized get()
{
return i;
}
, но это действительно даже не работало бы здесь, потому что, чтобы обеспечить, чтобы Ваш поток вызывающей стороны получил то же значение, которое он увеличил, необходимо будет гарантировать, что Вы атомарно увеличиваете и затем получаете, который Вы не делаете здесь - т.е. необходимо было бы сделать что-то как
synchronized int {
increment
return get()
}
В основном, синхронизация полезна для определения, которое операции, как должны гарантировать, выполнят ориентированный на многопотоковое исполнение (inotherwords, Вы не можете создать ситуацию, где отдельный поток подрывает Вашу операцию и заставляет Ваш класс вести себя нелогично или подрывает то, чем Вы ожидаете, что состояние данных будет). Это - на самом деле большая тема, чем к можно обратиться здесь.
Этот книжный Параллелизм Java на практике превосходен, и конечно намного более надежен, чем я.
В Java операции на ints являются атомарными так не, в этом случае Вы не должны синхронизироваться, если все, что Вы делаете, является 1 записью и 1 чтением за один раз.
, Если они были longs или удваиваются, действительно необходимо синхронизироваться, потому что для части длинного/двойного возможно быть обновленным, затем имейте другое чтение потока, затем наконец другая часть обновленного длинного/двойного.
Для простого помещения его Вы используете, синхронизировался, когда у Вас есть несколько потоков, получающих доступ к тому же методу того же экземпляра, который изменит состояние объектного/или приложения.
Это предназначено как простой способ предотвратить условия состязания между потоками, и действительно необходимо только использовать его, когда Вы - планирование наличия параллельных потоков, получающих доступ к тому же экземпляру, таких как глобальный объект.
Теперь при чтении состояния экземпляра объекта с параллельными потоками можно хотеть изучить java.util.concurrent.locks. ReentrantReadWriteLock - который в теории позволяет многим потокам читать за один раз, но только одному потоку позволяют записать. Таким образом в методе считывания и подающем примере метода, который все, кажется, дают, Вы могли сделать следующее:
public class MyClass{
private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
private int myValue = 0;
public void setValue(){
rwl.writeLock().lock();
myValue++;
rwl.writeLock().unlock();
}
public int getValue(){
rwl.readLock.lock();
int result = myValue;
rwl.readLock.unlock();
return result;
}
}