线程安全-001

例子程序:

/**
 * 多个线程一把锁
 * @author dev
 *
 */
public class MyThread extends Thread{
    
    private int count = 5;

    //synchronized
    @Override
    public void run() {
        count--;
        System.err.println(this.currentThread().getName() + " count = "+count);
    }
    
    public static void main(String[] args) {
        
        /**
         * 多个线程访问myThread的run方法时,以排队的方式进行处理(CPU分配的先后顺序排队)
         * 一个线程想要执行synchronized修饰的方法里的代码:
         * 1,尝试获得锁
         * 2,如果拿到该锁,执行synchronized代码体内容,拿不到锁,这个线程就会不断尝试获得这把锁,
         * 直到拿到未止,而且是多个线程同时去竞争这把锁(也就是有锁竞争的问题)
         * 
         */
        
        MyThread myThread = new MyThread();
        //参数:Runnable target, String name
        Thread t1 = new Thread(myThread,"t1"); 
        Thread t2 = new Thread(myThread,"t2");
        Thread t3 = new Thread(myThread,"t3");
        Thread t4 = new Thread(myThread,"t4");
        Thread t5 = new Thread(myThread,"t5");
    
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();    
    }
}
代码说明:
MyThread继承Thread,是一个线程类,有一成员变量count,重写run方法:对count值进行减减,打印当前线程名字和count值。
main方法:启动5个线程t1、t2、t3、t4、t5,把MyThread对象注入进去,启动5个线程。

执行main方法,结果:

   线程启动后,5个线程都等待着cpu的执行,所以5个线程的执行顺序是随机的,导致看到的t1、t2 、t3、 t4、 t5的输出顺序是随机的。对于count值,我们心里预期的应该输出 count=4、count=3、count=2、count=1、count=0,但是输出结果跟心理预期的是不一样的。这就是说,5个线程同时访问MyThread类的run方法,对count值进行减减,不是线程安全的。

将run方法加上synchronized 关键字,就是线程安全的:

//synchronized加锁
    @Override
    public synchronized void run() {
        count--;
        System.err.println(this.currentThread().getName() + " count = "+count);
    }

打印结果:

这和我们心里的预期是一样的,也就是线程安全的。这就和开篇说的线程安全的定义:当多个线程访问某一个类(对象或者方法)时,这个类始终都能表现出正确的行为,那么这个类(对象或方法)就是线程安全的。这里的正确的行为,就是指你心里预期的。

 run方法 加上synchronized加锁后,启动5个线程,当第一个线程拿到锁后,其他4个线程就会等待,等着第一个线程释放锁,一次类推。

多线程就是一个厕所,厕所门上有一个锁,外面5个人去抢这一把锁,谁抢到了锁,就可以进去上厕所,当第一个进去的出来后,其他4个人会同时去抢这把锁。所以会产生锁竞争的问题,当线程足够多的时候,锁竞争会导致CPU使用率过高,应尽量避免锁竞争。

 搞10000个线程,看看锁竞争cpu使用情况:

代码:

MyThread myThread = new MyThread();
        List<Thread> threads = new ArrayList<Thread>();
        for(int i=0;i<10000;i++){
            threads.add(new Thread(myThread,"t"+i)); 
        }
        for(Thread t : threads){
            t.start();
        }

CPU:

 

猜你喜欢

转载自www.cnblogs.com/lihaoyang/p/10538698.html
001
今日推荐