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