网站建设所需要的内容,棋牌游戏软件开发,青岛网信信息科技有限公司,机械加工网上平台文章目录 并发问题同步方法同步代码块 线程安全类型ArrayListHashtableHashMapVector 多线程共享数据引发的问题
模拟 “A” “B” “C” 三人抢票#xff0c;总票数10张#xff0c;打印抢票情况以及剩余票数。
public class Site implements Runnable {int count 10; // … 文章目录 并发问题同步方法同步代码块 线程安全类型ArrayListHashtableHashMapVector 多线程共享数据引发的问题
模拟 “A” “B” “C” 三人抢票总票数10张打印抢票情况以及剩余票数。
public class Site implements Runnable {int count 10; // 总票数int num 0; // 已抢票数Overridepublic void run() {while (true) {if (count 0) {break;}count--;num;System.out.println(Thread.currentThread().getName() 抢到第 num 张票剩余 count 张票);//休眠 模拟网络延时try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();
}}}}
public static void main(String[] args) {Site site new Site();Thread th1 new Thread(site,A);Thread th2 new Thread(site,B);Thread th3 new Thread(site,C);th1.start();th2.start();th3.start();
}问题 不是从第1张票开始 存在多人抢到一张票的情况 有些票号没有被抢到 … 多个线程操作同一共享资源时将引发数据不安全问题 并发问题
synchronized 在 Java 中是一种悲观锁Pessimistic Lock的形式。悲观锁假设最坏的情况即认为数据总是会被其他线程修改因此在处理数据之前就先获取锁。这样可以避免数据冲突但也可能导致较高的竞争开销。
同步方法
使用 synchronized 修饰的方法控制对类成员变量的访问synchronized 就是为当前的线程声明一把锁 访问修饰符 synchronized 返回类型 方法名参数列表{……} synchronized 访问修饰符 返回类型 方法名参数列表{……} 使用同步方法的网络购票
public class Site implements Runnable{int count 10; // 总票数int num 0; // 已抢票数Overridepublic void run() {while(true){if(qg()){ break; }//休眠 模拟网络延时try {Thread.sleep(500); // 休眠半秒} catch (InterruptedException e) {e.printStackTrace();}}}public synchronized boolean qg(){if(count 0){ return true; }count--;num;System.out.println(Thread.currentThread().getName()抢到第num张票剩余count张票);return false;}}同步代码块
使用 synchronized 关键字修饰的代码块
synchronized(syncObject){// 需要同步的代码
}syncObject 为需同步的对象通常为 this效果与同步方法相同
使用同步代码块的网络购票
public class Site implements Runnable{int count 10; // 总票数int num 0; // 已抢票数Overridepublic void run() {while(true){//同步synchronized (this){if(count 0){ break;}count--;num;System.out.println(Thread.currentThread().getName()抢到第num张票剩余count张票);}//休眠 模拟网络延时try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();
}}}}多个并发线程访问同一资源的同步代码块时 同一时刻只能有一个线程进入同步代码块 当一个线程访问一个同步代码块时其他同步代码块同样被锁定 当一个线程访问一个同步代码块时其他线程可以访问该资源的非同步代码
线程安全类型
为达到安全性和效率的平衡可以根据实际场景来选择合适的类型
方法是否同步效率比较适合场景线程安全是低多线程并发共享资源非线程安全否高单线程
HashtableHashMap继承关系实现了 Map 接口继承 Dictionary 类实现了 Map 接口继承 AbstractMap 类安全性线程安全效率较低非线程安全效率较高键值键和值都不允许为 null键和值都允许为 nullStringBufferStringBuilder安全性线程安全非线程安全适合场景适用于多线程环境中的字符串大量操作适用于单线程环境中的字符串拼接
ArrayList
非线程安全
// 查看 ArrayList 类的 add() 方法定义
public boolean add(E e) {ensureCapacityInternal(size 1); // 集合扩容确保能新增数据elementData[size] e; // 在新增位置存放数据return true;
}ArrayList 类的 add() 方法为非同步方法。当多个线程向同一个 ArrayList 对象添加数据时可能出现数据不一致问题
Hashtable
线程安全
HashtableString,String hashtable new Hashtable();
hashtable.put(,);public synchronized V put(K key, V value) {// Make sure the value is not nullif (value null) {throw new NullPointerException();}// Makes sure the key is not already in the hashtable.......
}HashMap
非线程安全
HashMap在多线程环境中可能会导致数据丢失或结构破坏。
HashMapString,String hashMap new HashMap();
hashMap.put(,);public V put(K key, V value) {return putVal(hash(key), key, value, false, true);
}Vector
线程安全
Vector vector new Vector();
vector.add();public synchronized boolean add(E e) {modCount;ensureCapacityHelper(elementCount 1);elementData[elementCount] e;return true;
}