Java线程 - Go语言中文社区

Java线程


1.2 何谓线程

1.2.1 单线程程序

  1. 在单线程程序中,"在某一时间点执行的处理"只有一个,因为 “正在执行程序的主体” 只有一个。
  2. Java程序执行时,至少会有一个线程在运行,即主线程

1.2.2. 多线程程序

  1. 启动新线程时调用的是 start 方法,而不是 run 方法。当然 run 方法是可以调用的,但调用它不会启动新的线程。
  2. 调用 start 方法后,程序会在后台启动新的线程,然后,由这个新线程调用 run 方法
  3. 输出结果显示,多线程情况下输出不一定按照代码顺序。
  4. 顺序、并行与并发:
  • 顺序(sequential)用于表示多个操作“依次处理”。比如把十个操作交给一个人处理时,这个人要一个一个地按顺序来处理。
  • 并行(parallel)用于表示多个操作“同时处理”。比如十个操作分给两个人处理时,这两个人就会并行来处理。
  • 并发(concurrent)相对于顺序和并行来说比较抽象,用于表示 “将一个操作分割成多个部分并且允许无序处理”。比如将十个操作分成相对独立的两类,这样便能够开始并发处理了。如果一个人来处理,这个人就是顺序处理分开的并发操作,而如果是两个人,这两个人就可以并行处理同一个操作。

1.3 线程的启动

1.3.1 启动线程的方法

  1. 利用Thread类的子类的实例启动线程。
  • 创建子类的实例并调用 start 方法
MyThread t = new MyThread();
t.start();
  1. 利用Runnable接口的实现类的实例启动线程。
  • 创建接口实现类的实例,把它作为参数传给Thread的构造函数
Runnable r = new MyThread();
Thread t = new Thread(r);
t.start();

1.3.2 程序的终止

Java程序的终止是指除守护线程(Daemon Thread)以外的线程全部终止。守护线程是执行后台作业的线程。我们可以通过setDaemon方法把线程设置为守护线程。

1.3.3 Thread类和Runnable接口

Thread类本身还实现了Runnable接口,并且持有run方法,但Thread类的run方法是去调用子类的run方法

1.4 线程的暂停

1.4.1 sleep方法的调用

  1. sleep方法的调用放在了try…catch中,这是因为,sleep方法有可能会抛出 InterruptedException 异常。
  2. 如果要中途唤醒被 Thread.sleep休眠的线程,则可以使用interrupt方法。

1.5 线程的互斥处理

1.5.1 synchronized方法

  1. 如果声明一个方法时,在前面加上关键字synchronized,那么这个方法就只能由一个线程运行。只能由一个线程运行是每次只能由一个线程运行的意思,并不是说仅能让某一特定线程运行。
  2. 如果有一个线程正在运行某个实例中的某个synchronized方法,则其他线程就无法运行该实例的所有synchronized方法,但非synchronized方法可以同时运行。
  3. 每个实例拥有一个独立的锁。因此,并不是说某一个实例中的synchronized方法正在执行中,其他实例中的synchronized方法就不可以运行了。

1.5.2 锁和监视

  1. 线程的互斥机制称为监视(monitor)。另外,获取锁有时也叫作“拥有(own)监视”或
    “持有(hold)锁”。
  2. 当前线程是否已获取某一对象的锁可以通过Thread.holdsLock方法来确认。当前线程已获取对象obj的锁时,可使用assert来像下面这样表示出来。
    assert Thread.holdsLock (obj);
  3. synchronized 实例方法是使用 this 的锁来互斥,synchronized 静态方法是使用该类的类对象的锁来互斥

1.6 线程的协作

1.6.1 线程控制方法

Java提供了用于执行线程控制的wait方法、notify方法和notifyAll方法。wait是让线程等待的方法,而notify和notifyAll是唤醒等待中的线程的方法。

1.6.2 等待队列

  1. 所有实例都拥有一个等待队列,它是在实例的wait方法执行后停止操作的线程的队列。打个比方来说,就是为每个实例准备的线程休息室。
  2. 在执行wait方法后,线程便会暂停操作,进入等待队列这个休息室。除非发生下列某一情况,否则线程会一直在等待队列中休眠。当下列任意一种情况发生时,线程便会退出等待队列:
  • 有其他线程的 notify 方法来唤醒线程
  • 有其他线程的 notifyAll 方法来唤醒线程
  • 有其他线程的 interrupt 方法来唤醒线程
  • wait方法超时

1.6.3 wait、notify、notifyAll

  1. 若要执行 wait、notify 和 notifyAll 方法,线程必须持有锁,否则会抛出 illegalMonitorstateException。但如果线程进入等待队列,便会释放其实例的锁。
  2. 假如在执行notify方法时,正在等待队列中等待的线程不止一个,对于 “这时该如何来选择线程” 这个问题规范中并没有作出规定。究竟是选择最先wait的线程,还是随机选择,或者采用其他方法要取决于Java平台运行环境。
  3. notify 方法仅唤醒一个线程,而 notifyAll 则唤醒所有线程,这是两者之间唯一的区别。
  4. wait、notify 和 notifyAll 都是 Object 类的方法,而非 Thread 独有。

线程状态迁移图

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/void_miss/article/details/88813183
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢