在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中,如果一個synchronized方法包含在同一個非同步的,可以另一種方法仍然可以訪問非同步的方法調用時間?
是的。其他方法可以訪問非同步方法。
基本上我問的是在synchronized方法中的所有東西都有一個鎖(包括對其他同步方法的調用)?
呃,是的。其他呼叫同步方法被鎖定。但是非同步方法沒有被鎖定。
此外,請記住,如果方法是static
那麼鎖定位於ClassLoader
中的Class
對象。
// 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個線程試圖在同一個實例上對方法進行操作,則會阻塞,直到另一個線程退出該方法。
所以我想在同步的方法中調用非同步方法不是一個好主意......因爲可以通過其他方法同時調用它們。 – dido 2012-03-01 23:39:07
如果這導致2個線程訪問需要同步的數據,那麼是的,這不是一個好主意。然而,這總是發生'toString()'和其他方法。它只取決於你的對象和用例。 – Gray 2012-03-01 23:42:40
我只想在這裏拋出一個同步方法,可以同時多次調用,只要它在不同的對象上調用即可。鎖適用於特定對象 - 類的實例 - 除非方法是靜態的。我認爲很容易忘記這一點,因爲很多人(包括所有當前的海報)都會對方法進行鎖定,就好像它應用於任何對象實例一樣。 – arcy 2012-03-02 03:28:51
如果線程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
/**/
}
}
公共類任務{
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();
}
}
}
公共類任務2 {
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. 從同步方法調用非同步方法
- 3. 從另一個同步方法調用同步方法是否安全?
- 4. 在另一個同步方法中引用同步方法
- 5. 線程調用非同步實例方法時的同步方法被調用
- 6. 靜態同步方法與非靜態同步方法
- 7. 異步方法調用同步方法
- 8. 同步方法調用另一個調用wait()的同步方法
- 9. 調用同步方法的同步方法,兩個同一對象
- 10. SynchronizationLockException(對象同步方法從非同步代碼塊調用。)釋放鎖時
- 11. 從同步方法調用同步方法的同步成本是多少?
- 12. 同步的方法和鎖
- 13. Java的同步方法調用不同步方法
- 14. S3方法是否同步?
- 15. WifiManager.setWifiEnabled方法是否同步?
- 16. 等待一個同步方法,其中調用異步方法
- 17. 如何從非異步方法異步調用異步方法
- 18. 同步方法
- 19. 同步方法
- 20. 同步方法
- 21. 對象同步方法在使用Mutex時從非同步塊調用
- 22. 非同步方法在異步調用堆棧
- 23. 在同步方法中調用異步
- 24. 是否有通用的方法來同步異步方法?
- 25. 這是異步調用同步方法的正確方法嗎?
- 26. 同步異步調用的方法?
- 27. 同步調用handle_asynchronously方法
- 28. 同步調用redis方法
- 29. 同步報表和單獨的非同步方法
- 30. ConcurrentModificationException的具有同步和非同步方法
對我的答案有任何反饋?請接受它,如果它幫助你。 – Gray 2014-01-10 14:07:20
我認爲格雷的回答必須被接受,因爲它完全回答了問題。 – Sankalp 2015-04-07 07:00:33