多线程

并发:指两个或多个事件在同一时间段内发生; 强调的是时间段.

多线程和进程的区别:

进程:有独立的内存空间,进程中的数据存放空间(堆空间和栈空间)是独立的,至少有一个线程。
线程:堆空间是共享的,栈空间是独立的,线程消耗的资源也比进程小,相互之间可以影响的,又称为轻型进程或进程元。 因为一个进程中的多个线程是并发运行的,那么从微观角度上考虑也是有先后顺序的,那么哪个线程执行完全取决于CPU调度器,程序员是控制不了的。我们可以把多线程并发性看作是多个线程在瞬间抢CPU资源,谁抢到资源谁就运行,这也造就了多线程的随机性。
多线程是为了同步完成多项任务,不是为了提高运行效率,而是为了提高资源使用效率来提高系统的效率。线程是在同一时间需要完成多项任务的时候实现的。
最简单的比喻多线程就像火车的每一节车厢,而进程则是火车。车厢离开火车是无法跑动的,同理火车也不可能只有一节车厢。多线程的出现就是为了提高效率。
创建线程的方法有两种:

方式1:继承java.lang.Thread类. 

方式2:实现java.lang.Runnable接口.

两者进行对比分析如下:因为java是单继承,我们继承了Thread类之后没办法继承其他类了,这是很不利于程序的拓展性的,而实现Runnable接口之后我们还可以继承其他的类,算是变相的实现了多继承吧;从功能上来说,都是创建了多线程,但是继承Thread类之后是无法共享同一份资源,也就是手这是多个线程执行多个任务,而实现Runnable接口则是多个线程共享一份资源,就是多个线程执行多个任务。

说到多线程,不得不说线程安全问题:

在线程进行并发的时候多个线程并发访问某一个共同资源的时候,可能会线程线程安全问题. 在多线程并发访问一个共同资源的时候,线程安全问题是存在的,只是不够明显. 习惯模拟网络延迟:Thread.sleep(100);让当前线程先休眠100毫秒,让其他线程获取执行的机会.这样很可能就会出现多个线程访问同一个资源的情况,出现这种情况,解决方案有三种:

1.同步代码块;

2.同步方法;

3.锁机制;

方式1:使用同步代码块(使用synchronized修饰的代码块).
      synchronized(同步监听对象){     
       需要同步的代码
       }

此时,同步监听对象,就使用此时多个线程共同访问的那一份资源.

比如,A,B,C三个线程: 此时,若A进入了synchronized代码块中,此时代码块会把其他线程排除在外. 只有当A线程从synchronized代码块中执行完毕,其他线程才有机会进入该代码块.

方式2:使用同步方法(使用synchronized修饰的方法).

      synchronized public 返回类型 方法名(参数列表){
          需要同步的代码     
      } 

同步方法的同步监听对象是谁? 若同步方法是非static方法,此时同步监听对象是:this. 若同步方法是static方法,此时同步监听对象是:当前方法所在类的字节码对象.

方式3:使用锁机制.

从Java5开始提供的,这种操作,更加面向对象.

ReentrantLock:一个可重入的互斥锁 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。

 

本篇文章主要讲了这些,总结一下:

1:什么是并发.

2:进程和线程的区别.
3:创建和启动线程的两种方式.

  a:继承Thread类.

  b:实现Runnable接口.

解决多线程并发时,线程不安全情况.

  a:使用同步代码块来解决.

  b:使用同步方法来解决.

  c:使用Lock来解决.

原文地址:https://www.cnblogs.com/kevinZhu/p/6930500.html