网站开发实例视频,wordpress社交分享国内,安徽省徽工建设集团网站,互联网公司有几家原子操作#xff1a;所谓原子操作是指不会被线程调度机制打断的操作#xff1b;这种操作一旦开始#xff0c;就一直运行到结束#xff0c;中间不会有任何 context switch #xff08;切[1] 换到另一个线程#xff09;。 关于我对原子操作的理解#xff1a;原子操作就类…原子操作所谓原子操作是指不会被线程调度机制打断的操作这种操作一旦开始就一直运行到结束中间不会有任何 context switch 切[1] 换到另一个线程。 关于我对原子操作的理解原子操作就类似于化学中的原子为不可分割的单位也就是如果把需要操作的代码块能够顺序执行中间不为被干扰。 这样就不会出现线程不安全情况案例中的购票系统出现负数的情况这种原子操作思想还是挺有用的在这提提自己也不了解-。 解决方案保证打印编号和操作必须同步执行:System.out.println(Thread.currentThread().getName()”—卖出的票”tickets–); 也就是上述代码中ticket–与输出同步执行不能因为某个线程输出后就休眠而不执行减减操作。 方式一、同步代码块 语法 synchronize同步锁{需要同步操作的代码}
案例
package com.test;//线程安全
public class Main { public static void main(String[] args){ SaleThread saleThreadnew SaleThread(); new Thread(saleThread,线程一).start(); new Thread(saleThread,线程二).start(); new Thread(saleThread,线程三).start(); new Thread(saleThread,线程四).start(); }
}
class SaleThread implements Runnable{ private int tickets10; public void run(){ //synchronized (this) {while(tickets0){ try{ Thread.sleep(10); }catch(InterruptedException e){ e.printStackTrace(); } System.out.println(Thread.currentThread().getName()---卖出的票tickets--); // } } }
}
*输出结果 线程二—卖出的票10 线程一—卖出的票9 线程四—卖出的票8 线程三—卖出的票7 线程二—卖出的票5 线程一—卖出的票6 线程三—卖出的票4 线程四—卖出的票3 线程一—卖出的票1 线程二—卖出的票2 线程三—卖出的票-1 线程四—卖出的票0* 分析上述结果中出现负数和0情况如果数据量大还会出现重复情况。 方式二、同步方法 使用synchronized修饰的方法就叫同步方法表示a线程在执行该方法的时候其他线程只能等待。 代码 synchronized public void run(){ while(tickets0){ try{ Thread.sleep(10); }catch(InterruptedException e){ e.printStackTrace(); } System.out.println(Thread.currentThread().getName()---卖出的票tickets--); } **问题来了上述代码中synchronized中的同步锁是谁**对于非static方法同步锁就是this对于static方法我们使用当前方法所在类的字节码对象当前类名.class方式三、同步锁-锁机制lock 为了保证每个线程都能正常执行原子操作java引入了线程同步机制。 同步监听对象/同步锁/同步监听器/互斥锁(a进去b被排斥保证只有一个进程执行) 对象的同步锁只是一个概念可以想象为在对象上标记一个锁。 java程序运行使用任何对象作为同步监听对象但是一般的我们试验当前并发访问的共同资源作为同步监听对象。 注意在任何时候最多允许一个线程拥有同步锁谁拿到锁就进入代码块其他线程只能等待。