美文网首页
Java多线程和线程同步

Java多线程和线程同步

作者: 如愿以偿丶 | 来源:发表于2020-11-09 16:34 被阅读0次

    1.进程和线程

     1.1.进程和线程

      1.操作系统中运行多个软件
      2.一个运行中的软件可能包含多个进程
      3.一个运行中的进程可能包含多个线程

     1.2.CPU线程和操作系统线程

      1.2.1.CPU线程
        1.多核CPU的每个核各自对立运行,因此每个核一个线程
        2.「四核⼋线程」:CPU硬件方在硬件级别对CPU进行了一核多线程的支持(本质上依然是每个核一个线程)

      1.2.2.操作系统线程
        1.操作系统利用时间分片的方式,把CPU的运行拆分给多条运行逻辑,即为操作系统的线程。

    2.线程使用

     2.1.Thread和Runnable
      //Thread
      Thread thread = new Thread(){
            @Override
            public void run() {
                Log.e("TAG","Thrad started------Thread");
           }
        };
      thread.start();
         
     //Runnable
     Runnable runnable = new Runnable() {
           @Override
           public void run() {
               Log.e("TAG","Thrad started------Runnable");
           }
       };
       Thread thread1 = new Thread(runnable);
       thread1.start();
    
     2.2.Executor 和线程池

      常用:newCachedThreadPool()

    //Executor
     Runnable runnable = new Runnable() {
        @Override
        public void run() {
             Log.e("TAG","runnable----------------------");
        }
      };
        Executor executor = Executors.newCachedThreadPool();
        executor.execute(runnable);
        executor.execute(runnable);
        executor.execute(runnable);       
    

    3.线程同步与线程安全

     3.1.synchronized方法
    private synchronized void count(int newValue) {
       x = newValue;
       y = newValue;
       if (x != y) {
           System.out.println("x: " + x + ", y:" + y);
       }
     }
    

    问题:
      当我们两个线程同时调用count方法,如果不添加synchronized关键字,会出现x!=y的情况。
    因为当线程1执行到count方法的x=newValue,突然切换时间片切换到线程2执行到y = newValue,此时x就会不等于y,此时就会出现数据问题,数据不同步问题。

    解决:
      添加synchronized关键字后,会把count方法作为一个整体,当线程1的count方法未执行行完成,此时其他线程执行count方法,此时线程1还持有锁,线程2只能等待线程1执行完成后才能执行count方法。保证数据同步问题。

     3.2.synchronized代码块
    private  void count(int newValue) {
      synchronized(this){
         x = newValue;
         y = newValue;
         if (x != y) {
             System.out.println("x: " + x + ", y:" + y);
         }
        }
     }
    

    synchronized关键字的本质:
      1.保证方法内部或代码块内部资源(数据)的互斥访问,即同一时间,由同一个Monitor(可认为是synchronized关键字)监视的代码,最多只能有一个线程在访问。
      2.保证线程之间对监视资源的数据同步,即,任何线程在获取到Monitor后的第一时间,会先将共享内存中的数据复制到自己的缓存中,任何线程在释放Monitor的第一时间会先将缓存中的数据复制到共享内存中。

    volatile关键字
      1.保证加了volatile关键字的字段的操作具有原子性和同步性,其中原子性相当于实现了针对单一字段的线程间互斥访问,因此volatile可以看做是简化版的synchronized
      2.volatile关键字只对基本类型(byte,short,int,long,char,float,double,boolean)的赋值操作和对象的引用赋值操作有效。

    4.总结

     4.1.线程安全问题的本质:

      在多个线程访问共同的资源时,在某一个线程对资源进行写操作的中途(写入已经开始,但还没结束),其他线程对这个写了一半的资源进行了读操作,或者基于这个写了一半的资源进行了写操作,导致数据出现错误。

     4.2.锁机制的本质:

      1.通过对共享资源进行访问限制,让同一时间只有一个线程可以访问资源,保证了数据的准确性。
      2.不论是线程安全问题,还是针对线程安全问题所衍生出的锁机制,他们的核心都是在共享的资源,而不是在某个方法或者某几行代码。

    相关文章

      网友评论

          本文标题:Java多线程和线程同步

          本文链接:https://www.haomeiwen.com/subject/bkblbktx.html