Java 多線程訪問同步方法的七種情況

1、兩個線程訪問一個對象的同步方法
public class SynchronizedObjectMethod3 implements Runnable{
    static SynchronizedObject instance=new SynchronizedObject();

    @Override
    public void run() {
        method();
    }

    public synchronized  void method(){
        System.out.println("我是對象所的方法修飾符形式,我叫"+Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"線程結束");
    }
    public static void main(String[] args){
        //兩個線程訪問一個對象的同步方法,對象爲instance實例
        Thread t1=new Thread(instance);
        Thread t2=new Thread(instance);
        t1.start();
        t2.start();
        while (t1.isAlive()||t2.isAlive()){

        }
        System.out.println("fininshed");
    }

}

2、兩個線程訪問的是兩個對象的同步方法,兩個對象一個爲instance1,另一個爲instance2
public class SynchronizedObject implements Runnable{
    static SynchronizedObject instance1=new SynchronizedObject();
    static SynchronizedObject instance2=new SynchronizedObject();
 /*   Object lock1=new Object();
    Object lock2=new Object();*/
    @Override
    public void run() {
        synchronized (this) {
            System.out.println("我是對象鎖的代碼塊形式,我叫" + Thread.currentThread().getName());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "運行結束");
        }


    }
    public static void main(String[] args){
        Thread t1=new Thread(instance1);
        Thread t2=new Thread(instance2);//兩個線程訪問的是兩個對象的同步方法,兩個對象一個爲instance1,另一個爲instance2
        t1.start();
        t2.start();
        while (t1.isAlive()||t2.isAlive()){

        }
        System.out.println("fininshed");
    }
}

3、兩個線程訪問synchronized的靜態方法
public class SynchronizedClassStatic4 implements Runnable {
    static SynchronizedClassStatic4 instance1=new SynchronizedClassStatic4();
    static SynchronizedClassStatic4 instance2=new SynchronizedClassStatic4();
    @Override
    public void run() {
        method();
    }

    public static synchronized void method(){
        System.out.println("我是類鎖的一種形式,我叫"+Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"線程結束");
    }
    public static void main(String[] args){//兩個線程訪問synchronized的靜態方法
       Thread t1=new Thread(instance1);
        Thread t2=new Thread(instance2);
        t1.start();
        t2.start();
        while (t1.isAlive()||t2.isAlive()){
        }
        System.out.println("fininshed");

    }
}

4、同時訪問同步方法和非同步方法。

public class SynchronizedYesAndNo6 implements Runnable{
    static SynchronizedYesAndNo6 instance=new SynchronizedYesAndNo6();
    @Override
    public void run() {
        if(Thread.currentThread().getName().equals("Thread-0")){
            method1();
        }else {
            method2();
        }

    }
    public synchronized  void method1(){
        System.out.println("我是加鎖的方法"+Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"線程執行結束");

    }

    public  void method2(){
        System.out.println("我是不加鎖的方法"+Thread.currentThread().getName()+"線程執行結束");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"線程執行結束");

    }
    public static void main(String[] args) throws InterruptedException{

        Thread t1=new Thread(instance);
        Thread t2=new Thread(instance);
        t1.start();
        t2.start();
        while (t1.isAlive()||t2.isAlive()){}
        System.out.println("ok");
        //結論:同步方法不會出現併發問題,非同步方法不會受到影響,出現併發問題。

    }
}

5、訪問同一個對象的不同的普通同步方法

public class SynchronizedDifferent7 implements Runnable {
    static SynchronizedDifferent7 instance=new SynchronizedDifferent7();
    @Override
    public void run() {
        if(Thread.currentThread().getName().equals("Thread-0")){
            method1();
        }else {
            method2();
        }

    }
    public synchronized  void method1(){
        System.out.println("我是加鎖的方法"+Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"線程執行結束");

    }

    public synchronized void method2(){
        System.out.println("我也是加鎖的方法"+Thread.currentThread().getName()+"線程執行結束");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"線程執行結束");

    }
    public static void main(String[] args) throws InterruptedException{

        Thread t1=new Thread(instance);
        Thread t2=new Thread(instance);
        t1.start();
        t2.start();
        while (t1.isAlive()||t2.isAlive()){}
        System.out.println("ok");

    }
}

6、同時訪問靜態synchronized方法和非靜態synchronized方法

public class SynchronizedStaticAndNormal8 implements Runnable{
    static SynchronizedStaticAndNormal8 instance=new SynchronizedStaticAndNormal8();
    @Override
    public void run() {
        if(Thread.currentThread().getName().equals("Thread-0")){
            method1();
        }else {
            method2();
        }

    }
    public static synchronized  void method1(){
        System.out.println("我是加鎖的靜態方法1"+Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"線程執行結束");

    }

    public synchronized void method2(){
        System.out.println("我也是加鎖的非靜態方法2"+Thread.currentThread().getName()+"線程執行結束");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"線程執行結束");

    }
    public static void main(String[] args) throws InterruptedException{

        Thread t1=new Thread(instance);
        Thread t2=new Thread(instance);
        t1.start();
        t2.start();
        while (t1.isAlive()||t2.isAlive()){}
        System.out.println("ok");

    }
}

7、方法拋異常後,會釋放鎖

public class SynchronizedException9 implements Runnable {
    static  SynchronizedException9 instance=new SynchronizedException9();
    @Override
    public void run() {
        if(Thread.currentThread().getName().equals("Thread-0")){
            method1();
        }else {
            method2();
        }

    }
    public  synchronized  void method1(){
        System.out.println("我是加鎖的靜態方法1"+Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
            throw new Exception();//異常拋出後,JVM會自動幫你釋放鎖,不需要自己手動釋放鎖。
        } catch (InterruptedException e) {
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"線程執行結束");
	   

 
  
    }

    public synchronized void method2(){
        System.out.println("我也是加鎖的非靜態方法2"+Thread.currentThread().getName()+"線程執行結束");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"線程執行結束");

    }
    public static void main(String[] args) throws InterruptedException{

        Thread t1=new Thread(instance);
        Thread t2=new Thread(instance);
        t1.start();
        t2.start();
        while (t1.isAlive()||t2.isAlive()){}
        System.out.println("ok");

    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章