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里的代码

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

  • 相关阅读:
    linux之awk命令
    HDU 2097 Sky数 进制转换
    HDU 2077 汉诺塔IV
    HDU 2094 产生冠军 dfs加map容器
    HDU 2073 叠框
    HDU 2083 简易版之最短距离
    HDU 2063 过山车 二分匹配
    天梯 1014 装箱问题
    天梯 1214 线段覆盖
    天梯 1098 均分纸牌
  • 原文地址:https://www.cnblogs.com/Summer7C/p/5004909.html
Copyright © 2011-2022 走看看