什么是线程?
线程是指程序在执行过程中,能够执行程序代码的一个执行单元。
线程有4种状态:运行,就绪,挂起和结束
线程与进程有什么区别?
进程是指一段正在执行的程序。
而线程有时也被称为轻量级进程,它是程序执行的最小单元,一个进程可以拥有多个线程
,各个线程之间共享程序的内存空间 (代码段、数据段和堆空间) 及一此游程级的资源(例如打开的文件),但是各个线程拥有自己的栈空间。
为什么要使用多线程?
-
使用多线程可以减少程序的响应时间。在单线程(单线程指的是程序执行过程中只有一个有效操作的序列,不同操作之间都有明确的执行先后顺序)的情况下,如果某个操作很耗时或陷入长时间的等待(如等待网络响应),此时程序将不会响应鼠标和键盘等操作,使用多线程后,可以把这个耗时的线程分配到一个单独的线程去执行,使程序具有更好的交互性。
-
与进程相比,线程的创建和切换开销更小。由于启动一个新的线程必须给这个线程分配独立的地址空间,建立许多数据结构来维护线程代码段、数据段等信息,而运行在同一进程内的线程共享代码段、数据段,线程的启动或切换的开销比进程少很多。同时多线程在数据共享方面效率非常高。
-
多CPU或多核计算机本身就具有执行多线程的能力,如果使用单个线程,将无法重复利用计算机资源,造成资源的巨大浪费。因此在多CPU计算机上使用多线程能提高CPU的利用率。
-
使用多线程能简化程序的结构,使程序便于理解和维护,一个复杂的进程可以分成多个线程来执行。
同步和异步?
同步
A线程要请求某个资源,但是此资源正在被B线程使用中,因为同步机制存在,A线程请求不到,怎么办,A线程只能等待下去
在多线程的环境中,经常会碰到数据的共享问题,即当多个线程需要访问同一个资源时,它们需要以某种顺序来确保该资源在某一时刻只能被一 个线程使用,否则,程序的运行结果将会是不可预料的,在这种情况下就必须对数据进行同步。
实现同步的方式有两种:
一种是利用同步代码块来实现同步;另一种是利用同步方法来实现同步。
异步
A线程要请求某个资源,但是此资源正在被B线程使用中,因为没有同步机制存在,A线程仍然请求的到,A线程无需等待
举个生活中的简单例子就可以区分同步与异步了。同步就是你喊我去吃饭,如果听到了,我就和你去吃饭;如果我没有听到,你就不停地喊,直到我告诉你听到了,我们才一起去吃饭。异步就是你喊我,然后自己去吃饭,我得到消息后可能立即走,也可能等到下班才去吃饭。
可以知道,同步最安全,最保险的。而异步不安全,容易导致死锁
,这样一个线程死掉就会导致整个进程崩溃,但没有同步机制的存在,性能会有所提升
run( )方法与start( )方法有什么区别?
通常,系统通过调用线程类的start()方法来启动一个 线程,此时该线程处于就绪状态而非运行状态,也就意味着这个线程可以被JVM来调度执行。在调度过程中,JVM 通过调用线程类的run( )方法来完成实际的操作,当run( )方法结束后,此线程就会终止。
如果直接调用线程类的run( )方法,这会被当作一个普通的函数调用,程序中仍然只有主线程这一个线程, 也就是说,start方法( )能够异步地调用run( )方法,但是直接调用run()方法却是同步的,因此也就无法达到多线程的目的。
多线程同步的实现方法有哪些?
-
synchronized关键字
-
synchronized方法
public synchronized void ThreadAccess();
-
synchronized块
synchronized(syncObject){ //访问syncObject的代码 }
-
-
wait()方法和notify()方法
-
Lock
sleep()方法和wait()方法有什么区别?
- 原理不同。
- sleep方法是Thread类的静态方法,是线程用来控制自身流程的,会使此线程暂停执行一段时间,而把执行机会让给其他线程,等计时时间一到,此线程会自动“苏醒”;
- wait方法是Object类的方法,用于线程间的通信会让当前拥有该对象锁的进程等待,直到其他线程调用notify方法时才醒来,不过也可以给它指定一个时间,自动“醒来”。
- 对锁的处理机制不同
- 使用区域不同