小伙伴们,在面试的时候是不是经常遇到与线程有关的题目呢? 下面我把线程做了总结(含代码实现),希望对你学习线程有帮助!
一、当我们谈到线程时,很自然地会想到进程。那么,进程与线程有什么区别呢?
1.进程间是独立的,表现在内存空间,上下文环境里;线程时运行在进程空间内的。
2.在不适用特殊技术的前提下,进程是无法突破进程边界存取其他进程内的存储空间的;但是线程由于身处在进程空间内,所以同一进程所产生的线程共享在同意内存空间里。
3.在同一进程中的两端代码不能同时执行,除非引入线程。
4.线程是属于进程的,当进程退出时,该进程所产生的线程也都会被强制退出并清除。
5.线程占用的资源远远要少于进程所占用的资源。
6.进程和线程都可以有优先级。
7.其实在线程系统中,进程也是一个线程,可以将其理解为一个程序的第一个线程。
二、线程是一个动态执行的过程,它也有一个从产生到死亡的过程。
1.生命周期的5种状态:
新建(new Thread):当创建Thread类的一个实例对象时,这个线程进入新建状态(未被启动)。例:Thread t = new Thread();
就绪(runnable):线程已经被启动,正在等待被分配给CPU时间片,就是说,此时线程正在就绪排列等候CPU资源。例:t.start();
运行(running):线程获得CPU资源正在执行任务(run()方法),此时,除非线程自动放弃CPU资源或者具有优先级更高的线程进入,否则线程将一直运行到结束。
死亡(dead):当线程运行完毕或被其他线程杀死,线程就进入死亡状态,这时线程不可能再进入就绪状态等待执行。
两种终止方式:自然终止:正常运行run()方法后终止。
异常终止:调用stop()方法让一个线程终止运行。
堵塞(blocked):由于某种原因导致正在运行的线程让出CPU并暂停自己的运行,就是所谓的堵塞状态。
正在睡眠:用sleep(long t)方法可以使线程进入睡眠状态。一个睡着的线程在指定的时间过去,可以进入就绪(runnable)状态。
正在等待:调用wait()方法。(调用notify()方法可以回到就绪(runnable)状态)
被另一个线程所阻塞:调用suspend()方法。(调用resume()方法可以恢复)
2.常用方法:
void run() 创建该类的子类时必须实现的方法
void start() 开启线程的方法
static void sleep(long t) 释放CPU的执行权,不释放锁
static void sleep(long millis,int nanos)
final void wait() 释放CPUT的执行权,释放锁
final void notify()
static void vied() 临时暂停当前线程(让线程将资源释放出来)
还有很多方法,自己看api,这里不多写了... ...
3.编写
(1)结束线程原理:就是让run方法结束。而run方法中通常会定义循环结构,所以只要控制住循环即可
(2)方法----可以boolean标记的形式完成,只要在某一情况下将标记改变,让循环停止即可让线程结束
(3)public final void join()//让线程加入执行,执行某一线程join方法的线程会被冻结,等待某一线程执行结束,该线程才会恢复到可运行状态
4.临界资源:多个线程间共享的数据成为临界资源
互斥锁:每个对象都对应于一个可以称为“互斥锁”的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。
Java对象默认是可以被多个线程共用的,只是需要时才启动“互斥锁”机制,成为专用对象。
关键字 synchronized 是用来与对象的互斥锁联系。
当某个对象用 synchronized 修饰时,说明该对象已启动“互斥锁”机制,在任一时刻只能由一个线程访问,即使该线程出现堵塞,该对象的被锁定状态也不会解除,其他线程也 不能访问该对象。
三、一个Java简单线程例子,帮助学习
java编写3个线程程序,分别 获得线程 名称,以1000毫秒、5000毫秒、10000毫秒分别执行,显示出来
- package org.song.thread;
- public class TestThread {
- /**
- * @param args
- */
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- new MyThread("线程1",1000).start();
- new MyThread("线程2",5000).start();
- new MyThread("线程3",10000).start();
- }
- }
- class MyThread extends Thread{
- private long m = 0;
- MyThread(String nameString,long m){
- super(nameString);
- this.m = m;
- }
- public void run(){
- int x = 0;
- try {
- while (x<10) {
- System.out.println(Thread.currentThread().getName() + " 线程正在运行");
- x++;
- Thread.sleep(m);
- }
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
运行结果:
- 线程2 线程正在运行
- 线程3 线程正在运行
- 线程1 线程正在运行
- 线程1 线程正在运行
- 线程1 线程正在运行
- 线程1 线程正在运行
- 线程1 线程正在运行
- 线程1 线程正在运行
- 线程2 线程正在运行
- 线程1 线程正在运行
- 线程1 线程正在运行
- 线程1 线程正在运行
- 线程1 线程正在运行
- 线程2 线程正在运行
- 线程3 线程正在运行
- 线程2 线程正在运行
- 线程2 线程正在运行
- 线程3 线程正在运行
- 线程2 线程正在运行
- 线程2 线程正在运行
- 线程3 线程正在运行
- 线程2 线程正在运行
- 线程3 线程正在运行
- 线程2 线程正在运行
- 线程2 线程正在运行
- 线程3 线程正在运行
- 线程3 线程正在运行
- 线程3 线程正在运行
- 线程3 线程正在运行
- 线程3 线程正在运行