多线程

多线程

基本概念

  • 进程:计算机在执行的程序的实体
  • 线程:一个程序内部的顺序控制流
  • 一个进程中可以包含一个或多个线程;一个线程就是一个程序内部的一条执行线索
  • 每个进程有独立的代码和数据空间,进程的切换会有很大的的开销
  • 同一类线程共享代码和数据空间,每个线程有独立运行的栈和程序计数器,线程切换的开销小

多线程实现的方式

  1. 创建线程类
  • 继承Thread类
  • 或实现Runnable接口
  1. 通过Thread类构造器来创建线程对象
  • Thread()
  • Thread(Runnable target)
  1. 通过start()方法激活线程对象
  2. 线程执行
1
//线程类
2
public class ThreadDemo extends Thread{
3
    public void run(){
4
        ......
5
        //执行的代码
6
    }
7
}
8
9
//线程调用
10
public class TestThread{
11
    ThreadDemo t1=new ThreadDemo();
12
    ThreadDemo t2=new ThreadDemo();
13
    t1.start();
14
    t2.start();
15
    ......
16
}

线程的声明周期

线程中的主要方法

线程的优先级

Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程,线程调度器按照线程的优先级来决定应调度哪个线程来执行。
有三个优先级:

  • Thread.MIN_PRIORITY——1
  • Thread.NORM_PRIORITY——5
  • Thread.MAX_PRIORITY——10

    线程的休眠

  • sleep()

让线程种植一段时间的静态方法,在睡眠期满的瞬间,再次调用该线程不一定会恢复他的执行。

1
Thread.sleep(long millis)
2
//暂时停止执行millis毫秒
  • join()
    导致当前线程等待,直到调用这个join方法的线程终止
1
join();
2
join(long millis);等待执行millis毫秒
3
join(long millis,int nanos);//等待执行millis毫秒,nanaos纳秒
  • yield()
    为其他可行的线程提供执行机会
    静态方法——Thread.yield()

线程的中止

  • 自动终止:一个线程完成执行后,不能再次执行
  • 手动终止
  1. stop()——已经过时,基本不用
  2. interrupt()———粗暴的终止方式
  3. 可通过使用一个标志指示run方法退出,从而终止线程

线程的高级操作

1
void wait()

导致当前的线程等待,直到其他线程调用此对象的notify()方法或notiftAll()方法

1
void notify()

唤醒在此对象监视器上等待的单个线程

1
void notifyAll()

唤醒在此对象监视器上等待的所有线程

线程同步

为了确保两个线程在同时访问同一个文件的时,保证数据的一致性。
原理是:使用线程同步语句时,保证只有一个线程在执行。

概念:每个对象都有一个锁标志,使用synchronized可与锁标志交互,保证里面的对象是线程同步的。

实现同步的两种方式

  • synchronized方法
1
synchronized void methodA(){
2
    
3
}
  • synchronized语句
1
synchronized(Object object){
2
    ......
3
    //要同步的语句
4
}

注意:受到synchronized保护的程序代码块和方法中,要访问的对象属性必须设定为private,因为如果不设定为private,那么就可以用不同的方式来访问它,这样就达不到保护的效果了。

synchronized方法和synchronized语句的比较

synchronized方法

  • 优点:可以具体知道哪些方法是被synchronized保护的。
  • 缺点:方法中的有些内容不需要同步,会降低效率
    synchronized语句
  • 优点:可以专门针对某段代码,可以取得不同对象的锁。
  • 缺点:无法明确得知哪些方法是被synchronized保护的。