java 線程安全不線程不安全

常常看到一些類,有的說線程安全,有的說線程不安全,頓時懵逼。java

線程安全不安全,主要是在多線程執行的狀況下,若是因爲線程之間搶佔資源而形成程序的bug即爲線程不安全,下面就拿arraylist 和Vector來舉個例子:安全

這裏的arraylist 是線程不安全的,Vector是線程安全的多線程

package Thread;

import java.util.List;
import java.util.concurrent.CountDownLatch;

public class MyThread  implements Runnable{
	private List<Object> list;
	private CountDownLatch countDownLatch;
	public MyThread(){}
	public  MyThread(List<Object> list,CountDownLatch countDownLatch){
		this.list=list;
		this.countDownLatch=countDownLatch;
	}
	@Override
	public void run() {
		//給每一個線程添加10個元素
		for(int i=0;i<10;i++){
			list.add(new Object());
		}
		//完成一個子線程
		countDownLatch.countDown();
	}
}

  

package Thread;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.CountDownLatch;

public class ThreadTest {
	/**
	 * 這裏要比較的是arraylist 和Vector來測試
	 * arraylist 是線程不安全的
	 * Vector  線程安全的
	 * 
	 */
	public static void test(){
		//用來測試的list集合
		List<Object> list= new ArrayList<Object>();
		//List<Object> list = new Vector<Object>();
		//線程數
		int threadCount =10000;
		//用來讓主線等待thread 個執行完畢
		CountDownLatch  count=new CountDownLatch(threadCount);
		for(int i=0;i<threadCount;i++){
			Thread thread=new Thread(new MyThread(list, count));
			thread.start();
		}
		try {
			//主線程全部都執行完成後,再向下執行
			count.await();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(list.size());
	}
	public static void main(String[] args) {
		for(int i=0;i<10;i++){
			test();
		}
	}
}

 運行結構:ide

99995
99998
99989
99973
99894
99970
99974
99977
99990
99989測試

當使用Vector時,即把測試的集合換一下this

package Thread;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.CountDownLatch;

public class ThreadTest {
	/**
	 * 這裏要比較的是arraylist 和Vector來測試
	 * arraylist 是線程不安全的
	 * Vector  線程安全的
	 * 
	 */
	public static void test(){
		//用來測試的list集合
		//List<Object> list= new ArrayList<Object>();
		List<Object> list = new Vector<Object>();
		//線程數
		int threadCount =10000;
		//用來讓主線等待thread 個執行完畢
		CountDownLatch  count=new CountDownLatch(threadCount);
		for(int i=0;i<threadCount;i++){
			Thread thread=new Thread(new MyThread(list, count));
			thread.start();
		}
		try {
			//主線程全部都執行完成後,再向下執行
			count.await();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(list.size());
	}
	public static void main(String[] args) {
		for(int i=0;i<10;i++){
			test();
		}
	}
}

  這樣運行的結果:線程

100000
100000
100000
100000
100000
100000
100000
100000
100000
100000blog

很明顯,使用Vector 這個類運行正確,這就是所謂的線程安全資源

固然,這只是代碼層面上的,其實多線程不安全,主要由於cpu分配機制,誰得到了cpu誰就能執行,所以形成了線程的不安全.同步

咱們能夠使用synchronized  關鍵字來同步代碼塊,達到線程安全:

下面舉個synchronized同步的例子:

package Thread1;

public class Bank {
	private int sum = 0;

	public void add(int n) {
		sum = sum + n;
		System.out.println("sum= " + sum);
	}
}



package Thread1;
public class Cus implements Runnable {
	Bank b = new Bank();
	@Override
	public void run() {
		for (int i = 0; i < 3; i++) {
			b.add(100);
		}

	}
}





package Thread1;

public class Test {
	public static void main(String[] args) {
		Cus c = new Cus();
		for (int i = 0; i < 3; i++) {
			new Thread(c).start();
		}
	}
}

  沒有使用synchronized修飾的時候,運行結構是:

sum= 100
sum= 400
sum= 500
sum= 300
sum= 200
sum= 600
sum= 800
sum= 700
sum= 900

 

固然synchronized 必需要在線程運行的代碼塊中修飾:

package Thread1;

public class Bank {
	private int sum = 0;

	public void add(int n) {
		sum = sum + n;
		System.out.println("sum= " + sum);
	}
}



package Thread1;
public class Cus implements Runnable {
	Bank b = new Bank();
	@Override
	
	public void run() {
		synchronized(this){
			for (int i = 0; i < 3; i++) {
				b.add(100);
			}
		}
	}
}



package Thread1;

public class Test {
    public static void main (String [] args) {
        Cus c = new Cus();
        for(int i=0;i<3;i++){
        	new Thread(c).start();
        }
    }
}

  這樣保證,每次只有一個線程在運行,結果爲:

sum= 100
sum= 200
sum= 300
sum= 400
sum= 500
sum= 600
sum= 700
sum= 800
sum= 900

OK,OVER

天天進步一點點,堅持下去

相關文章
相關標籤/搜索