synchronized 到底鎖的是誰?
修飾方法:
1、靜態(tài)方法
2、非靜態(tài)方法,鎖住的是方法的調(diào)用者
修飾代碼塊
1、synchronized修飾非靜態(tài)方法 鎖住的是方法的調(diào)用者
鎖住實例
流程:
1、線程A先拿到synModel對象然后給這個 synModel對象加上鎖–接著等3s執(zhí)行輸出結(jié)束
2、線程B等1s后運行,此時 synModel對象 已經(jīng)被 A拿到,所以他只能等待 等3s后,線程A釋放 synModel對象,然后獲取對象執(zhí)行輸出結(jié)束
public class SynchronizedTest {
public static void main(String[] args) throws InterruptedException {
SynModel synModel = new SynModel();
new Thread(()->{
synModel.fun1();
},"A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
synModel.fun2();
},"B").start();
}
}
class SynModel{
public synchronized void fun1() {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1...");
}
public synchronized void fun2(){
System.out.println("2...");
}
}
情況1 不會排隊
注意:下面這種情況是不會排隊的,因為鎖的是實例。
public class SynchronizedTest {
public static void main(String[] args) throws InterruptedException {
SynModel synModel1 = new SynModel();
SynModel synModel2 = new SynModel();
new Thread(()->{
synModel1.fun1();
},"A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
synModel2.fun2();
},"B").start();
}
}
class SynModel{
public synchronized void fun1() {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1...");
}
public synchronized void fun2(){
System.out.println("2...");
}
}
2 、修飾靜態(tài)方法
只是把SynModel中的方法變成了靜態(tài)的,注意此時鎖住的是 SynModel這個類,不是鎖的實例。會排隊 先輸出1后輸出2
public class SynchronizedTest {
public static void main(String[] args) throws InterruptedException {
SynModel synModel1 = new SynModel();
SynModel synModel2 = new SynModel();
new Thread(()->{
synModel1.fun1();
},"A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
synModel2.fun2();
},"B").start();
}
}
class SynModel{
public static synchronized void fun1() {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1...");
}
public static synchronized void fun2(){
System.out.println("2...");
}
}
3、代碼塊
synchronized (this){}
鎖住的是SynModel這個對象??梢钥吹窖h(huán)的五次都是同一個SynModel對象。所以五個線程 某個時刻只能有一個線程拿到這個SynModel對象 這個資源。
每個線程會依次輸出start end
public class SynchronizedTest {
public static void main(String[] args) {
final SynModel synModel = new SynModel();
for (int i = 0; i < 5; i++) {
synModel.fun3();
}
}
}
class SynModel{
public void fun3(){
synchronized (this){
System.out.println("start");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end");
}
}
}
如果把對象放在循環(huán)里面,此時就是五個線程拿五個資源了。并沒有去爭奪資源文章來源:http://www.zghlxwxcb.cn/news/detail-745788.html
public class SynchronizedTest {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
final SynModel synModel = new SynModel();
new Thread(()->{
synModel.fun3();
}).start();
}
}
}
class SynModel{
public void fun3(){
synchronized (this){
System.out.println("ThreadName:"+Thread.currentThread().getName()+"start");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadName:"+Thread.currentThread().getName()+"end");
}
}
}
鎖住SynModel.class 此時五個線程就會競爭,因為鎖住的是 SynModel這個類,而不是實例對象了。文章來源地址http://www.zghlxwxcb.cn/news/detail-745788.html
public class SynchronizedTest {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
final SynModel synModel = new SynModel();
new Thread(()->{
synModel.fun3();
}).start();
}
}
}
class SynModel{
public void fun3(){
synchronized (SynModel.class){// this SynModel.class
System.out.println("ThreadName:"+Thread.currentThread().getName()+"start");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadName:"+Thread.currentThread().getName()+"end");
}
}
}
到了這里,關(guān)于synchronized 到底鎖的是誰?的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!