java线程不安全详解,线程安全理解

  java线程不安全详解,线程安全理解

  00-1010线程的状态是枚举类型线程。状态

  公共静态void main(String[]args){ for(Thread。状态状态:线程。state . values()){ system . out . println(state);}}新3360安排了工作,但还没开始。

  RUNNABLE:可以工作。可以分为正在工作和即将开始工作。就绪状态

  BLOCKED:这些都意味着排队等别的东西。

  WAITING:这些都意味着排队等别的东西。

  TIMED_WAITING:这些都意味着排队等别的事情。

  终止:工作完成。

  

一、观察线程的所有状态

 

  新的:Thread对象可用,但PCB不可用。

  RUNNABLE:线程正在CPU上执行或即将在CPU上执行(PCB在就绪队列中,可以随时调度)

  WAITING:wait方法导致

  TIMED _ WAITING:sleep方法导致

  阻塞:等待锁定原因

  终结的:对象还在,但是PCB不见了。

  public static void main(String[]args){ Thread t=new Thread(){ @ Override public void run(){ for(int I=0;i 100 _ 00I){ } } };System.out.println(线程启动前: t . getstate());t . start();while(t . isa live()){ system . out . println(线程运行: t . getstate());} System.out.println(线程结束后: t . getstate());}

  00-1010不安全线程的原因

  线程被抢先执行。

  线程不安全是所有邪恶的根源。线程之间的调度完全是内核的责任,这在用户代码中是无法察觉和控制的。线程之间,谁先执行,谁后执行,谁在哪里下CPU就执行,这个过程是用户无法控制和感知的。

  自动增量操作不是原子的。

  它可以一次分成三个步骤。

  将内存中的数据读入CPU

  将数据1放入CPU

  将计算的数据写回到存储器中。

  如果两个线程串行执行,结果是2。

  如果两个线程并行执行,当线程1执行到一半时,该线程也会执行。此时递增两次,结果却是1。

  需要保证线程1保存,线程2再次加载,然后计算结果才是正确的。

  多个线程试图修改同一个变量。

  如果一个线程修改了一个变量,那么它就是线程安全的。

  如果多个线程读取同一个变量,那么它是线程安全的。

  如果多线程修改不同的变量。线程安全

  内存可见性导致线程安全问题。

  指令重新排序

  Java编译器在编译代码时,会对指令进行优化,调整指令顺序,保证原有逻辑不变,提高程序运行效率。

  00-1010锁同步

  开锁

  静态类计数器{ public int count=0;public void increase(){ count;} }公共静态void main(String[] args)抛出interrupted exception { Counter Counter=new Counter();Thread t1=new Thread(){ @ Override public void run(){ for(int I=0;液性指数

  t; 50000; i++){ counter.increase(); } } }; Thread t2 = new Thread(){ @Override public void run() { for (int i = 0; i < 50000; i++){ counter.increase(); } } }; t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(counter.count); }

 

  

 

  

 

   已加锁

  

static class Counter{ public int count = 0; synchronized public void increase(){ count++; } } public static void main(String[] args) throws InterruptedException { Counter counter = new Counter(); Thread t1 = new Thread(){ @Override public void run() { for (int i = 0; i < 50000; i++){ counter.increase(); } } }; Thread t2 = new Thread(){ @Override public void run() { for (int i = 0; i < 50000; i++){ counter.increase(); } } }; t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(counter.count); }

 

  

 

  此处的synchronized就是针对counter这个对象来加锁,进入increase方法内部,就把加锁状态设为ture,increase方法退出之后,就把加锁状态设为false,如果某个线程已经把加锁状态设为ture,此处的其他的线程尝试去加锁,就会阻塞

  synchronized的特性——刷新内存

  synchronized 的工作过程:

          1. 获得互斥锁

          2. 从主内存拷贝变量的最新副本到工作的内存

          3. 执行代码

          4. 将更改后的共享变量的值刷新到主内存

          5. 释放互斥锁

  synchronized的特性——互斥

  

 public static void main(String[] args) { Object locker = new Object(); Thread t1 = new Thread(){ @Override public void run() { Scanner scanner = new Scanner(System.in); synchronized (locker) { System.out.println("输入一个整数"); int num = scanner.nextInt(); System.out.println("num= " + num); } } }; t1.start(); Thread t2 = new Thread(){ @Override public void run() { while (true){ synchronized (locker){ System.out.println("线程2获取到锁"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } }; t2.start(); }

 

  一旦线程一获取到锁,并且没有释放的话,线程2就会一直在锁这里阻塞等待

  

 public static void main(String[] args) { Object locker1 = new Object(); Object locker2 = new Object(); Thread t1 = new Thread(){ @Override public void run() { Scanner scanner = new Scanner(System.in); synchronized (locker1) { System.out.println("输入一个整数"); int num = scanner.nextInt(); System.out.println("num= " + num); } } }; t1.start(); Thread t2 = new Thread(){ @Override public void run() { while (true){ synchronized (locker2){ System.out.println("线程2获取到锁"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } }; t2.start(); }

 

   不是同一把锁,就不回出现竞争,就没有互斥了。

  

public static void main(String[] args) { Object locker1 = new Object(); Object locker2 = new Object(); Thread t1 = new Thread(){ @Override public void run() { Scanner scanner = new Scanner(System.in); synchronized (locker1.getClass()) { System.out.println("输入一个整数"); int num = scanner.nextInt(); System.out.println("num= " + num); } } }; t1.start(); Thread t2 = new Thread(){ @Override public void run() { while (true){ synchronized (locker2.getClass()){ System.out.println("线程2获取到锁"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } }; t2.start(); }

 

  这个代码中,两个线程都在针对locker1和locker2的类对象进行竞争,此处的locker1和locker2的类型都是Object,对应的对象都是相同的对象。 

  到此这篇关于Java线程安全状态专题解析的文章就介绍到这了,更多相关Java 线程安全内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: