В Java, если синхронизированный метод содержит вызов несинхронизированного, может ли другой метод по-прежнему обращаться к несинхронизированному методу в то же время? В основном, что я спрашиваю, все в синхронизированном методе имеет блокировку (включая вызовы для других синхронизированных методов)? Большое спасибоЕсли синхронизированный метод вызывает другой несинхронизированный метод, существует ли блокировка несинхронизированного метода
ответ
Если вы находитесь в методе synchronized
, тогда звонки на другие методы, которые также являются другими потоками заблокированы. Однако вызовы несинхронизированных методов другими потоками - это , а не заблокировано - каждый может вызвать их одновременно.
public synchronized void someSynchronizedMethod() {
...
someNonSynchronizedMethod();
...
}
// anyone can call this method even if the someSynchronizedMethod() method has
// been called and the lock has been locked
public void someNonSynchronizedMethod() {
...
}
Кроме того, если вы звоните someSynchronizedMethod()
, но случается в методе someNonSynchronizedMethod()
, вы по-прежнему держать блокировку. Блокировка включена, когда вы вводите синхронизированный блок и отключается при выходе из этого метода. Вы можете вызывать всевозможные другие несинхронизированные методы, и они все равно будут заблокированы.
Но вы просите разные вещи в вашем вопросе:
В Java, если синхронизированный метод содержит вызов к несинхронизированному, может другой способ получить доступ к несинхронизированному методу в том же время?
Да. Другие методы могут получить доступ к несинхронизированным методам.
В принципе, я спрашиваю, есть ли у всего синхронизированного метода блокировка (включая вызовы другим синхронизированным методам)?
Э-э, да. Другие звонки на синхронизированы методы заблокированы. Но несинхронизированные методы не заблокированы.
Кроме того, помните, что если метод static
, то замок находится на объекте Class
в ClassLoader
.
// this locks on the Class object in the ClassLoader
public static synchronized void someStaticMethod() {
Если метод является методом экземпляра, то блокировка находится на экземпляре класса.
// this locks on the instance object that contains the method
public synchronized void someInstanceMethod() {
В этих 2 случаях есть 2 разных замка.
Наконец, когда вы имеете дело с synchronized
методами экземпляра, каждый экземпляр класса - это то, что заблокировано. Это означает, что два потока могут быть в одном методе synchronized
одновременно с различными экземплярами. Но если 2 потока пытаются работать с методами synchronized
в одном экземпляре, каждый будет блокироваться до тех пор, пока другой не выйдет из этого метода.
Итак, я думаю, было бы неплохо вызвать несинхронизированные методы в синхронизированных ... потому что они могут быть вызваны одновременно другим методом. – dido
Если это вызывает 2 потока для доступа к данным, которые необходимо синхронизировать, то да, это не очень хорошая идея. Однако это происходит постоянно с помощью 'toString()' и других методов. Это зависит только от вашего объекта и прецедента. – Gray
Я хотел бы просто добавить сюда, что синхронный метод можно вызывать одновременно любое количество раз, если он вызывается на разные объекты. Блокировка применяется к конкретному объекту - экземпляру класса - если этот метод не является статическим. Я думаю, что это легко забыть, поскольку многие люди (включая все текущие плакаты) говорят о блокировке метода, как если бы он применялся независимо от экземпляра объекта. – arcy
Если поток A вызывает синхронизированный метод M1, который, в свою очередь, вызывает несинхронизированный метод M2, тогда поток B все равно может вызывать M2 без блокировки.
Синхронный метод получает и освобождает встроенную блокировку объекта, на который он вызывается. Вот почему он может блокироваться. Несинхронизированный метод не пытается получить блокировку (если это явно не указано в коде).
Таким образом, если вам необходимо обеспечить взаимное исключение для M2, вы должны синхронизировать его независимо от того, синхронизированы ли его вызывающие абоненты (например, M1) или нет.
Блокировка относится к резьбе , а не к методу (точнее, к его раме стека). Так получилось, что если у вас есть синхронизированный метод, вам гарантируется, что поток будет владеть блокировкой до начала запуска метода, и затем выпустит его.
Другой поток может вызывать второй несинхронизированный метод. Несинхронизированный метод может быть вызван любым потоком в любое время.
Замок не относится к нити. Блокировка фактически принадлежит объекту (или классу в случае блокировки уровня класса), и поток получает блокировку объекта (или класса в случае блокировки уровня класса) в синхронном контексте. Теперь в java нет распространения блокировки, как описано выше. Вот небольшая демонстрация:
общественного класса TestThread {
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
ThreadCreator1 threadCreator1 = new ThreadCreator1();
ThreadCreator2 threadCreator2 = new ThreadCreator2();
Thread t1 = new Thread(threadCreator1,"Thread 1");
Thread t3 = new Thread(threadCreator1,"Thread 3");
Thread t2 = new Thread(threadCreator2,"Thread 2");
t1.start();
Thread.sleep(2000);
t3.start();
}
}
общественного класса ThreadCreator1 реализует Runnable {
private static final Task task= new Task();
private static final Task2 task2= new Task2();
@Override
public void run() {
try {
if(Thread.currentThread().getName().equals("Thread 1"))
task.startTask2(task2);
if(Thread.currentThread().getName().equals("Thread 3"))
task2.startTask();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// TODO Auto-generated method stub
/**/
}
}
общественного класса Task {
public static final Task task = new Task();
public static List<String> dataList = new ArrayList<String>();
ReentrantLock lock = new ReentrantLock();
public void startTask2(Task2 task2) throws InterruptedException
{
try{
lock.lock();
//new Task2().startTask();
task2.startTask();
}
catch(Exception e)
{
}
finally{
lock.unlock();
}
}
}
общественного класса Task2 {
ReentrantLock lock = new ReentrantLock();
public void startTask() throws InterruptedException
{
try{
//lock.lock();
for(int i =0 ;i< 10;i++)
{
System.out.println(" *** Printing i:"+i+" for:"+Thread.currentThread().getName());
Thread.sleep(1000);
}
}
catch(Exception e)
{
}
/*finally
{
lock.unlock();
}*/
}
}
Просто я использовал повторно входимый запирать здесь. Если приведенный выше код запущен, то между потоком 1 и потоком 3 будет чередоваться, но если часть блокировки класса Task2 раскоментирована, тогда не будет чередования, и поток, который сначала получит блокировку, полностью завершит, то он освободит замок, а затем другой поток может продолжить.
- 1. несинхронизированный метод может получить доступ другой нитью ,,,,,,,
- 2. TDD - проверка, если один метод вызывает другой
- 3. Проверьте, что один метод метода вызывает другой
- 4. Синхронизированный метод в производном классе
- 5. Может ли пружинные транзакции синхронизировать синхронизированный метод?
- 6. Это как один метод вызывает другой метод?
- 7. Вызов метода, если вызван другой метод
- 8. JUnit: Как проверить, вызывает ли метод другой метод?
- 9. rspec проверить, если один метод вызывает другой метод
- 10. Синхронизированный метод против ReentrantLock
- 11. Два метода (один синхронизированный другой нет) и два потока
- 12. Возможно ли получить метод name, который вызывает другой метод?
- 13. Как использовать синхронизированный метод?
- 14. Синхронизированный метод Java
- 15. Синхронизированный метод in for loop
- 16. Имеет ли синхронизированный метод фиксацию на этом
- 17. Как прервать синхронизированный метод, который блокирован
- 18. тестирования, метод компонента вызывает другой метод
- 19. Должен ли это быть синхронизированный метод?
- 20. Синхронизированный метод, вызванный swingWorker прерван?
- 21. EJB вызывает другой метод EJB
- 22. Синхронизированный блокировка объекта Result Set?
- 23. Как реализован синхронизированный метод AnyRef?
- 24. Модульное тестирование метод, который вызывает другой метод другого класса
- 25. Hibernate Оптимистическая блокировка метод
- 26. Метод содержит другой метод
- 27. Java синхронизированный метод не синхронизирован
- 28. Асинхронный метод вызывает вызов вызова метода синхронизации
- 29. Есть ли несинхронизированный java.util.Stack?
- 30. Метод принудительного переопределения, если другой метод переопределен
Любые отзывы о моем ответе? Пожалуйста, примите это, если это поможет вам. – Gray
Я думаю, что ответ Грея должен быть принят, поскольку он отвечает именно на то, что задают. – Sankalp