java:多線程的 共享資源沖突問題


一,java中使用Thread類實現多線程。

1,如果有兩以上的線程同時訪問同一個共享資源,可能造成線程沖突,線程沖突會造成數據丟失、重復等嚴重問題。

以下通過兩個線程同時訪問同一個類,來表現線程沖突,如果產生沖突便會打印輸出。

例:

package Thread;

public class Tested {

    String name;
    public static void main(String[] args) {
        Tested b=new Tested();
        Thread a=new Thread() {
            public void run() {
                try {
                    while(true) {
                    Thread.sleep(2000);
                    b.aa("ls");
                    }
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            
        };
        a.start();
        
        Thread e=new Thread() {
            public void run() {
                try {
                    while(true) {
                    Thread.sleep(2000);
                    b.aa("aas");
                    }
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            
        };
        e.start();
    }
    
    public void aa(String name) {
        this.name=name;
        eqrr(name);
    }
    public void eqrr(String name) {
        if(!(name==this.name)) {
            System.out.println(this.name+""+name);
        }
    }
}

 2,解決方法可以使用synchronized關鍵字讓線程同步。

例:

package thinkmore;

import java.util.Scanner;

/*線程的沖突
    在多個線程訪問同一個對象的同一個屬性時,才會出現線程沖突,線程沖突會造成數據丟失、重復等嚴重問題。
   為了避免這個問題可以synchronized關鍵字讓線程同步。


   */
public class Test {
    String name;
    public static void main(String[] args) {
        final Test obj=new Test();
        final Test obj2=new Test();
        final Thread t=new Thread(){
            @Override
            public  void run(){
                while (true){
                    try {
                        obj.setName("張三");
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        t.start();
        final Thread t2=new Thread(){
            @Override
            public  void run(){
                while (true){
                    try {
                        obj2.setName("李四");
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        t2.start();
    }
   /*
1,放在函數中鎖住整個函數,只有前一個線程執行完下一個函數才能訪問
2,放在代碼塊中,鎖住需要共享的資源,推薦使用
*/
public /*synchronized*/ void setName(String name){ // synchronized(this) { this.name = name; equalsName(name); // } } public void equalsName(String name){ if(name!=this.name) System.out.println(name+" "+this.name); } }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM