线程安全

单线程至关于一我的作一件事,而多线程程序中,当须要多个线程共享同一个数据时,一个线程对共享的数据进行修改时,在他没有完成相关操做以前不容许其余线程进行相关操做,不然会出现线程安全问题。当对存在安全隐患的数据加锁后,会致使程序的性能下降,因此,若是是多个线程操做同一个数据,必定要选择线程安全的方法,若是不是,能够选择线程不安全的方式来处理问题。java

package pers.zhb.runnable;

public class MyThread implements Runnable {
    private int tickets = 10;

    public void run() {
        while (true) {
            if (tickets > 0)
                System.out.println(Thread.currentThread().getName()
                        + "售票窗口,售卖了" + tickets-- + "号票");
            else
                System.exit(0);
        }

    }

}
package pers.zhb.runnable;

public class RunnableDemo {
    public static void main(String[] args) {
        MyThread mt=new MyThread();
        Thread thread1 = new Thread(mt);
        Thread thread2 = new Thread(mt);
        Thread thread3 = new Thread(mt);
        Thread thread4 = new Thread(mt);
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();

    }
}

能够看出,10号票在被1号窗口卖出后,又被2号窗口卖了一次,显然这是不符合常理的。产生的缘由是这样的:2号线程开始执行,tickets为10,进行了 if (tickets > 0);语句的执行,能够继续往下执行了,可是他没有抢夺到CPU资源,接着是1号线程读取数据10,进行判断能够执行,1号线程执行完后,2号线程依旧没有抢夺到CPU资源,只能继续等待。接着是3号线程、0号线程进行相关操做。当2号线程抢夺到CPU资源时,他的数据仍是10,就形成了有重复票的状况。安全

添加同步语句:多线程

package pers.zhb.runnable;

public class MyThread implements Runnable {
    private int tickets = 10;
    Object lock = new Object();

    public void run() {

        synchronized (lock) {
            while (true) {
                if (tickets > 0)
                    System.out.println(Thread.currentThread().getName()
                            + "售票窗口,售卖了" + tickets-- + "号票");
                else
                    System.exit(0);
            }
        }

    }

}
package pers.zhb.runnable;

public class RunnableDemo {
    public static void main(String[] args) {
        MyThread mt=new MyThread();
        Thread thread1 = new Thread(mt);
        Thread thread2 = new Thread(mt);
        Thread thread3 = new Thread(mt);
        Thread thread4 = new Thread(mt);
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();

    }
}

建立同步方法:性能

package pers.zhb.runnable;

public class MyThread implements Runnable {
    private int tickets = 10;
    Object lock = new Object();

    public void run() {
        while (true)
            lock();

    }

    public synchronized void lock() {
        while (true) {
            if (tickets > 0)
                System.out.println(Thread.currentThread().getName()
                        + "售票窗口,售卖了" + tickets-- + "号票");
            else
                System.exit(0);
        }
    }
}
package pers.zhb.runnable;

public class RunnableDemo {
    public static void main(String[] args) {
        MyThread mt=new MyThread();
        Thread thread1 = new Thread(mt);
        Thread thread2 = new Thread(mt);
        Thread thread3 = new Thread(mt);
        Thread thread4 = new Thread(mt);
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();

    }
}

 

ReentrantLock (重入锁):

能够对资源重复加锁:spa

 

package pers.zhb.runnable;

import java.util.concurrent.locks.ReentrantLock;

public class MyThread implements Runnable {
    private int tickets = 10;

    ReentrantLock lock = new ReentrantLock();

    public void run() {

        while (true) {
            lock.lock();
            if (tickets > 0)
                System.out.println(Thread.currentThread().getName()
                        + "售票窗口,售卖了" + tickets-- + "号票");

            else
                System.exit(0);

        }

    }

}

 

package pers.zhb.runnable;

public class RunnableDemo {
    public static void main(String[] args) {
        MyThread mt=new MyThread();
        Thread thread1 = new Thread(mt);
        Thread thread2 = new Thread(mt);
        Thread thread3 = new Thread(mt);
        Thread thread4 = new Thread(mt);
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();

    }
}