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

天天进步一点点,坚持下去

相关文章
相关标签/搜索