zoukankan      html  css  js  c++  java
  • Java多线程学习笔记(二)

    三 多线程执行的共享数据和非共享数据:

    共享数据:就是每个线程执行的时候共享数据使用,比如这个线程一个为5的数据,减少为4之后,另一个线程执行拿到的数据是4,两个线程执行的数据是共享的。

    非共享数据:各个线程执行的数据不受其他线程数据的改变而改变。

    1 非共享数据:

     1 package link.summer7c.test;
     2 
     3 public class Test{
     4     public static void main(String[] args){
     5         MyThread2 a=new MyThread2("A");
     6         MyThread2 b=new MyThread2("B");
     7         MyThread2 c=new MyThread2("C");
     8         a.start();
     9         b.start();
    10         c.start();
    11     }
    12 }
    13 class MyThread2 extends Thread{
    14     private int count=5;
    15     public MyThread2(String name){
    16         super();
    17         this.setName(name);
    18     }
    19     public void run(){
    20         super.run();
    21         while(count>0){
    22             count--;
    23             System.out.println(this.currentThread().getName()+":count:"+count);
    24         }
    25     }
    26 }

    程序运行结果为:

    C:count:4
    B:count:4
    A:count:4
    B:count:3
    C:count:3
    C:count:2
    C:count:1
    C:count:0
    B:count:2
    A:count:3
    B:count:1
    A:count:2
    B:count:0
    A:count:1
    A:count:0

    从结果我们可以看见,3个线程的数据之间互不影响,变量减少按照各自的减法进行。这就是非共享的数据,这种做法通常在一些多线程并发操作中使用,各个数据没有相互影响。

    2 共享数据:

    各个线程之间的数据是共享的,他们的数据受其他线程的运行而影响。

     1 package link.summer7c.test;
     2 
     3 public class Test{
     4     public static void main(String[] args){
     5         MyThread3 myThread=new MyThread3();
     6         Thread a=new Thread(myThread,"A");
     7         Thread b=new Thread(myThread,"B");
     8         Thread c=new Thread(myThread,"C");
     9         a.start();
    10         b.start();
    11         c.start();
    12     }
    13 }
    14 class MyThread3 extends Thread{
    15     private int count=4;
    16         public void run(){
    17             super.run();
    18         count--;
    19           System.out.println(this.currentThread().getName()+":count:"+count);
    20     }
    21 }    

    运行结果有很多种:

    A:count:3
    B:count:2
    C:count:1

    或者:

    A:count:2
    B:count:2
    C:count:1

    这种运行结果可能会发现有些问题,就是出现了相同的数据。

    这个之后来讨论。

    构造方法public Thread(Runnable target, String name)

    共享数据的main方法中并不是new了多个对象,而是new个一个我们的类,然后new了3个Thread对象,调用了public Thread(Runnable target, String name)构造方法。

    共享数据的时候还要不能出现循环,如果一个线程开始循环,那么其他循环就得不到运行的机会了。

    三 线程安全的问题

    在共享数据的时候,我们会看到多个运行及结果很奇特,比如在运行的时候会出现2个相同的数据,这就牵扯到了线程安全的问题,如果在多线程中出现了:

    A:count:2
    B:count:2
    C:count:1

    这种情况,就称作线程不安全。举个例子,我们再抢火车票,每个客户都是一个线程,那么我们需要线程之间是安全的,不然就会发生两个座位同时被买走的可能性,发生这样的情况很不好。为了解决线程安全性我们可以使用同步锁,也就是每个线程之间要同步数据,不能发生线程之间不同步导致的线程不安全情况。多线程之间的同步可以通过在run方法之前加入synchronized关键字来实现,这样就不会出现两个数据相同的情况了。

    class MyThread3 extends Thread{
        private int count=4;
        synchronized public void run(){
            super.run();
            count--;
            System.out.println(this.currentThread().getName()+":count:"+count);
        }
    }

    synchronized可以在任意对象和方法上加锁,加锁的代码称为“互斥区”或者临界区。加上锁之后线程会是这样的:

    程序运行->拿锁->如果拿到锁了执行synchronized里的代码

           ->如果没有拿到就不断的尝试知道拿到->执行synchronized里的代码

    =========================================

  • 相关阅读:
    Javascript 入门 document
    JavaScript 入门 (一)
    Python 之 Json序列化嵌套类
    [20171113]修改表结构删除列相关问题3.txt
    [20171113]修改表结构删除列相关问题2.txt
    [20171113]修改表结构删除列相关问题.txt
    [20171110]_allow_read_only_corruption参数.txt
    [20171107]dbms_shared_pool.pin补充.txt
    [20171107]dbms_shared_pool.pin.txt
    [20171106]修改show spparameter的显示宽度.txt
  • 原文地址:https://www.cnblogs.com/Summer7C/p/5004909.html
Copyright © 2011-2022 走看看