zoukankan      html  css  js  c++  java
  • 1.2.3实例变量与线程安全

    自定义线程类中实例变量针对其他线程可以有共享与不共享的区分,这在多线程中的交互是一个技术点。

    (1)不共享数据的情况

    多个线程实例

     1 package com.cky.thread;
     2 
     3 /**
     4  * Created by chenkaiyang on 2017/11/27.
     5  */
     6 public class MyThreadTwo extends Thread{
     7 
     8     private int count = 5;
     9     public MyThreadTwo (String name) {
    10         super();
    11         this.setName(name);
    12     }
    13     @Override
    14     public void run() {
    15         super.run();
    16         while(count > 0) {
    17             count --;
    18             System.out.println("由" +this.currentThread().getName() +"计算,count="+count);
    19         }
    20 
    21     }
    22 }
     1 package com.cky.test;
     2 
     3 import com.cky.thread.MyThreadTwo;
     4 
     5 /**
     6  * Created by chenkaiyang on 2017/11/27.
     7  */
     8 public class Test2 {
     9     public static void main(String[] args) {
    10         MyThreadTwo a = new MyThreadTwo("A");
    11         MyThreadTwo b = new MyThreadTwo("B");
    12         MyThreadTwo c = new MyThreadTwo("C");
    13         a.start();
    14         b.start();
    15         c.start();
    16     }
    17 }
    D:itjdk1.8injava -Didea.launcher.port=7533 "-Didea.launcher.bin.path=D:itideaIntelliJ IDEA 2016.3.3in" -Dfile.encoding=UTF-8 -classpath "D:itjdk1.8jrelibcharsets.jar;D:itjdk1.8jrelibdeploy.jar;D:itjdk1.8jrelibextaccess-bridge-64.jar;D:itjdk1.8jrelibextcldrdata.jar;D:itjdk1.8jrelibextdnsns.jar;D:itjdk1.8jrelibextjaccess.jar;D:itjdk1.8jrelibextjfxrt.jar;D:itjdk1.8jrelibextlocaledata.jar;D:itjdk1.8jrelibext
    ashorn.jar;D:itjdk1.8jrelibextsunec.jar;D:itjdk1.8jrelibextsunjce_provider.jar;D:itjdk1.8jrelibextsunmscapi.jar;D:itjdk1.8jrelibextsunpkcs11.jar;D:itjdk1.8jrelibextzipfs.jar;D:itjdk1.8jrelibjavaws.jar;D:itjdk1.8jrelibjce.jar;D:itjdk1.8jrelibjfr.jar;D:itjdk1.8jrelibjfxswt.jar;D:itjdk1.8jrelibjsse.jar;D:itjdk1.8jrelibmanagement-agent.jar;D:itjdk1.8jrelibplugin.jar;D:itjdk1.8jrelib
    esources.jar;D:itjdk1.8jrelib
    t.jar;F:springboot	hreaddemooutproduction	hreaddemo;D:itideaIntelliJ IDEA 2016.3.3libidea_rt.jar" com.intellij.rt.execution.application.AppMain com.cky.test.Test2
    由B计算,count=4
    由C计算,count=4
    由A计算,count=4
    由C计算,count=3
    由B计算,count=3
    由C计算,count=2
    由A计算,count=3
    由C计算,count=1
    由B计算,count=2
    由C计算,count=0
    由A计算,count=2
    由B计算,count=1
    由B计算,count=0
    由A计算,count=1
    由A计算,count=0
    
    Process finished with exit code 0

    结果分析,这里一共创建了3个线程实例,每个线程都有各自的count变量,各自递减自己的变量,这就说明这个是变量不共享,不存在多个线程共同访问同一个实例的情况。

    (2)共享数据的情况

    共享数据的情况就是多个线程可以访问同一个变量

     1 package com.cky.thread;
     2 
     3 /**
     4  * Created by chenkaiyang on 2017/11/27.
     5  */
     6 public class MyThreadThird  extends Thread{
     7     private int count = 5;
     8     @Override
     9     public void run() {
    10         super.run();
    11         count -- ;
    12         System.out.println("由" + this.currentThread().getName()+"计算count="+count);
    13     }
    14 }
     1 package com.cky.test;
     2 
     3 import com.cky.thread.MyThreadThird;
     4 
     5 /**
     6  * Created by chenkaiyang on 2017/11/27.
     7  */
     8 public class Test3 {
     9     public static void main(String[] args) {
    10         MyThreadThird mythread = new MyThreadThird();
    11         Thread a = new Thread(mythread, "A");
    12         Thread b = new Thread(mythread, "B");
    13         Thread c = new Thread(mythread, "C");
    14         Thread d = new Thread(mythread, "D");
    15         Thread e = new Thread(mythread, "E");
    16 
    17         a.start();
    18         b.start();
    19         c.start();
    20         d.start();
    21         e.start();
    22 
    23 
    24     }
    25 }
    1 D:itjdk1.8injava -Didea.launcher.port=7534 "-Didea.launcher.bin.path=D:itideaIntelliJ IDEA 2016.3.3in" -Dfile.encoding=UTF-8 -classpath "D:itjdk1.8jrelibcharsets.jar;D:itjdk1.8jrelibdeploy.jar;D:itjdk1.8jrelibextaccess-bridge-64.jar;D:itjdk1.8jrelibextcldrdata.jar;D:itjdk1.8jrelibextdnsns.jar;D:itjdk1.8jrelibextjaccess.jar;D:itjdk1.8jrelibextjfxrt.jar;D:itjdk1.8jrelibextlocaledata.jar;D:itjdk1.8jrelibext
    ashorn.jar;D:itjdk1.8jrelibextsunec.jar;D:itjdk1.8jrelibextsunjce_provider.jar;D:itjdk1.8jrelibextsunmscapi.jar;D:itjdk1.8jrelibextsunpkcs11.jar;D:itjdk1.8jrelibextzipfs.jar;D:itjdk1.8jrelibjavaws.jar;D:itjdk1.8jrelibjce.jar;D:itjdk1.8jrelibjfr.jar;D:itjdk1.8jrelibjfxswt.jar;D:itjdk1.8jrelibjsse.jar;D:itjdk1.8jrelibmanagement-agent.jar;D:itjdk1.8jrelibplugin.jar;D:itjdk1.8jrelib
    esources.jar;D:itjdk1.8jrelib
    t.jar;F:springboot	hreaddemooutproduction	hreaddemo;D:itideaIntelliJ IDEA 2016.3.3libidea_rt.jar" com.intellij.rt.execution.application.AppMain com.cky.test.Test3
    2 由A计算count=3
    3 由D计算count=0
    4 由E计算count=1
    5 由C计算count=2
    6 由B计算count=3
    7 
    8 Process finished with exit code 0

    结果分析,上面将一个线程对象传递到其他的线程中进行调用,相当于一个多个线程实例调用同一个线程对象,共享线程对象中的变量。

    结果中A和B同时输出3,实际我们想要的结果是依次递减,产生了非线程安全的问题。

    由于线程执行的随机性,所以产生了这样的结果,这时就需要让多个线程进行同步,也就是按顺序执行run方法里的内容,就是让一个线程执行完run方法里的代码后,再让cpu切换到另一个线程

    使用synchronized关键字

     1 package com.cky.thread;
     2 
     3 /**
     4  * Created by chenkaiyang on 2017/11/27.
     5  */
     6 public class MyThreadThird  extends Thread{
     7     private int count = 5;
     8     @Override
     9     synchronized  public void run() {
    10         super.run();
    11         count -- ;
    12         System.out.println("由" + this.currentThread().getName()+"计算count="+count);
    13     }
    14 }

    再执行上面的test,结果如下(说明线程安全了)

    D:itjdk1.8injava -Didea.launcher.port=7536 "-Didea.launcher.bin.path=D:itideaIntelliJ IDEA 2016.3.3in" -Dfile.encoding=UTF-8 -classpath "D:itjdk1.8jrelibcharsets.jar;D:itjdk1.8jrelibdeploy.jar;D:itjdk1.8jrelibextaccess-bridge-64.jar;D:itjdk1.8jrelibextcldrdata.jar;D:itjdk1.8jrelibextdnsns.jar;D:itjdk1.8jrelibextjaccess.jar;D:itjdk1.8jrelibextjfxrt.jar;D:itjdk1.8jrelibextlocaledata.jar;D:itjdk1.8jrelibext
    ashorn.jar;D:itjdk1.8jrelibextsunec.jar;D:itjdk1.8jrelibextsunjce_provider.jar;D:itjdk1.8jrelibextsunmscapi.jar;D:itjdk1.8jrelibextsunpkcs11.jar;D:itjdk1.8jrelibextzipfs.jar;D:itjdk1.8jrelibjavaws.jar;D:itjdk1.8jrelibjce.jar;D:itjdk1.8jrelibjfr.jar;D:itjdk1.8jrelibjfxswt.jar;D:itjdk1.8jrelibjsse.jar;D:itjdk1.8jrelibmanagement-agent.jar;D:itjdk1.8jrelibplugin.jar;D:itjdk1.8jrelib
    esources.jar;D:itjdk1.8jrelib
    t.jar;F:springboot	hreaddemooutproduction	hreaddemo;D:itideaIntelliJ IDEA 2016.3.3libidea_rt.jar" com.intellij.rt.execution.application.AppMain com.cky.test.Test3
    由A计算count=4
    由E计算count=3
    由D计算count=2
    由C计算count=1
    由B计算count=0
    
    Process finished with exit code 0

    结果分析:

    synchronized可以在任意对象及方法上枷锁,而加锁的这段代码叫做互斥区

    总结:当一个线程想要执行同步方法里的代码,首先线程会尝试拿这把锁,如果能拿到这把锁,那么这个线程就能执行synchronize里的代码,如果拿不到这把锁,这个线程就会不断尝试那这把锁

    ,直到拿到为止,而且是多个线程同时去争抢这个锁

    非线程安全:多个线程对同一个对象中的同一个实例变量进行操作出现值被更改,值不同步,出现影响程序执行流程的情况。

  • 相关阅读:
    JQuery实现数组移除指定元素
    美团酒旅面经
    搜狗一面
    360面经
    头条面经
    搜狐笔试题
    kolakoski序列
    函数的节流
    隐藏元素的几种方法
    移动端适配与响应式布局
  • 原文地址:https://www.cnblogs.com/edison20161121/p/7954463.html
Copyright © 2011-2022 走看看