線程同步是指對共享資源,若不是共享資源則不涉及線程同步問題。
synchronized方法可以鎖定對象,也可以鎖定代碼塊。
當鎖定對象時,修飾在類的方法前面。記住:若兩個線程同時訪問一個對象的不同方法,且對象有一個synchronized方法和一個非synchronized方法,則是兩個線程並不涉及同步問題。只有當訪問同一個對象的synchronsized方法(可以是不同的synchronized方法)時纔會有同步。
比如對象toy有如下兩個方法
package concurrent1; public class toy { private int number; public toy(){ number = 100; } synchronized public void paint() { System.out.println("thread:"+Thread.currentThread().getName() + ":paint begin"); try{ int i = (int) (Math.random()*1000); Thread.sleep(i); } catch(Exception e) { } System.out.println("thread:"+Thread.currentThread().getName()+":paint"); System.out.println("thread:"+Thread.currentThread().getName() + ":paint end"); } synchronized public void write() { System.out.println("thread:"+Thread.currentThread().getName() + ":write begin"); try{ int i = (int) (Math.random()*1000); Thread.sleep(i); } catch(Exception e) { } System.out.println("thread:"+Thread.currentThread().getName()+":write"); System.out.println("thread:"+Thread.currentThread().getName() + ":write end"); } }
package concurrent1; public class Test { public static void main(String[] args) { // TODO Auto-generated method stub toy mytoy = new toy(); boy myboy = new boy(mytoy); boy youboy = new boy(mytoy); myboy.setName("myboy"); youboy.setName("youboy"); myboy.start(); youboy.start(); } }
結果:
thread:myboy:write begin thread:myboy:write thread:myboy:write end thread:myboy:paint begin thread:myboy:paint thread:myboy:paint end thread:youboy:write begin thread:youboy:write thread:youboy:write end thread:youboy:paint begin thread:youboy:paint thread:youboy:paint end
若將paint方法前的synchronized取消掉,輸出如下,可以看出write方法是異步執行的,只有paint方法是同步執行的。
thread:myboy:write begin thread:youboy:write begin thread:myboy:write thread:myboy:write end thread:myboy:paint begin thread:myboy:paint thread:myboy:paint end thread:youboy:write thread:youboy:write end thread:youboy:paint begin thread:youboy:paint thread:youboy:paint end