什么是线程安全问题:
当多个线程共享同一个全局变量,并做写的操作的时候,可能会受到其他线程的干扰,导致数据有问题,这种现象就叫做线程安全问题。
全局变量 与 局部变量,谁会有线程安全问题 ?
全局变量才会有线程安全问题。在方法内部的局部变量中,每个线程都有自己的局部变量,相互不会干扰。
这里说全局变量有安全问题,就在说一个面试题(我面试全友家私的时候面试官问我的问题):String ,StringBuffer,StringBuilder 什么时候使用他们 ?
首先,String是每个String类型的变量都会存储在常量池中,且不会被回收,所以用String对性能有所影响。
StringBuffer 和 StringBuilder是对象,可以被GC回收。
StringBuffer是线程安全的,但是效率低,所以如果是定义全局变量使用StringBuffer。
但是由于方法内部定义变量,没有线程安全问题,也就是说,方法内部的变量线程全都是安全的,所有在方法内部定义变量,最好使用线程不安全的StringBuilder。
public class CountThread implements Runnable { /** * 需求现在有10张火车票,有两个窗口同时抢火车票,请使用多线程模拟抢票效果。 * <p> * 下面的写法有线程安全问题,原因就是多个线程共享了同一个全局变量。 */ private int count = 10; public void run() { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } while (count > 0) { System.out.println(Thread.currentThread().getName() + ",出售第" + (10 - count + 1) + "票"); count--; } } } public class Test { /** * 结果: * <p> * 线程2,出售第1票 * 线程2,出售第2票 * 线程1,出售第1票 * 线程1,出售第4票 * 线程1,出售第5票 * 线程1,出售第6票 * 线程2,出售第3票 * 线程1,出售第7票 * 线程2,出售第8票 * 线程1,出售第9票 * 线程2,出售第10票 * <p> * 因为多个线程同时写操作了同一个 全局变量,所有出现了线程安全问题。 */ public static void main(String[] args) { CountThread c1 = new CountThread(); CountThread c2 = new CountThread(); Thread thread1 = new Thread(c1, "线程1"); Thread thread2 = new Thread(c1, "线程2"); thread1.start(); thread2.start(); } }