并发(2)

目录

6.通常线程有哪几种使用方式?

7.基础线程机制有哪些?

8.线程的中断方式有哪些?

9.线程的互斥同步方式有哪些?如何比较和选择?

10.Synchronized可以作用在哪里?


6.通常线程有哪几种使用方式?

有三种使用线程的方法:

实现Runnable接口;

实现Callable接口;

集成Thread类。

实现Runnable和Callable接口的类只能当做一个可以在线程中运行的任务,不是真正意义上的线程,因此最后还需要通过Thread来调用。可以说任务是通过线程驱动从而执行的。

7.基础线程机制有哪些?

Executor管理多个异步任务的执行,而无需程序员显式地管理线程的生命周期。这里的异步是指多个任务的执行互不干扰,不需要进行同步操作。

主要有三种Excutor:

1.CachedThreadPool:一个任务创建一个线程;

2.FixedThreadPool:所有任务只能使用固定大小的线程。

3.SingleThreadExecutor:相当于大小为1的FixedThreadPool。

Daemon

守护线程是程序运行时在后台提供服务的线程,不属于程序中不可或缺的部分。

当所有非守护线程结束时,程序也就终止,同时会杀死所有守护线程。

main()属于非守护线程。使用setDaemon()方法将一个线程设置为守护线程。

sleep()

Thread.sleep(millisec)方法会休眠当前正在执行的线程,Millisec单位为毫秒。

sleep()可能会抛出InterruptedException,因为异常不能跨线程传播回main()中,因此必须在本地进行处理。线程中抛出的其他异常也同样需要在本地进行处理。

yield()

对静态方法Thread.yield()调用声明了当前线程已经完成了声明周期中最重要的部分,可以切换给其他线程来执行。该方法只是对县城调度器的一个建议,而且也只是建议具有相同优先级的其他线程可以运行。

8.线程的中断方式有哪些?

一个线程执行完毕之后会自动结束,如果在运行过程中发生异常也会提前结束。

InterruptedException

通过调用一个线程的interrupt()来中断该线程,如果该线程处于阻塞,限期等待或者无限期等待状态,那么就会抛出InterruptedException,从而提前结束该线程。但是不能中断I/O阻塞和synchronized锁阻塞。

对于以下代码,在main()中启动一个线程之后再中断他,由于线程中调用了Thread.sleep()方法,因此会抛出InterruptedException,从而提前结束线程,不执行之后的语句。

 

interrupted()

如果一个线程的run()方法执行一盒无限循环,并且没有执行sleep()等会抛出InterruptedException的操作,那么调用线程的interrupt()方法就无法使线程提前结束。

但是调用interrupt()方法会设置线程的中断标记,此时调用Interrupt()方法会返回true。因此可以在循环体中使用interrupted()方法来判断线程是否处于中断状态,从而提前结束线程。

Excutor的中断操作

调用Excutor的shutdown()方法会等待线程都执行完毕后再关闭,但是如果调用的是shutdownNow()方法,则相当于调用每个线程的interrupt()方法。

9.线程的互斥同步方式有哪些?如何比较和选择?

Java提供了两种锁机制来控制多个线程对共享资源的互斥访问,第一个是JVM实现的synchronized,而另一个是JDK实现的ReentrantLock。

1.锁的实现

synchronized时JVM实现的,而ReentrantLock是JDK实现的。

2.性能

新版本Java对Synchronized进行了很多优化,例如自旋锁等,synchronized与ReentrantLock大致相同。

3.等待可中断

当持有锁的线程长期不释放锁的时候,正在等待的线程可以选择放弃等待,改为处理其他事情。ReentrantLock可中断,而synchronized不行。

4.公平锁

公平锁是指多个线程在等待同一个锁时,必须按照申请锁的时间顺序来一次获得锁。synchronized中的锁是非公平的,ReentrantLock默认情况下也是非公平的,但是也可以是公平的。

5.锁绑定多个条件

一个ReentrantLock可以同时绑定多个Condition对象。

10.Synchronized可以作用在哪里?

对象锁

方法锁

类锁