解决Java多线程中11个常见问题

  • 格式:docx
  • 大小:26.21 KB
  • 文档页数:6

下载文档原格式

  / 6
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

解决Java多线程中11个常见问题

1、线程是什么?

简单来说,线程是进程中独立运行的子任务。

2、创建线程的方式

方式一:将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法

方式二:声明实现 Runnable 接口的类。该类然后实现 run 方法

推荐方式二,因为接口方式比继承方式更灵活,也减少程序间的耦合。

3、获取当前线程信息?

Thread.currentThread()

4、线程的分类

线程分为守护线程、用户线程。线程初始化默认为用户线程。

setDaemon(true) 将该线程标记为守护线程或用户线程。

特性:设置守护线程,会作为进程的守护者,如果进程内没有其他非守护线程,那么守护线程也会被销毁,即使可能线程内没有运行结束。

5、线程的生命周期

线程是一个动态执行的过程,它也有一个从产生到死亡的过程。生命周期的五种状态:

新建(new Thread):当创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动)。

例如:Thread t1=new Thread();

就绪(runnable):线程已经被启动,正在等待被分配给CPU时间片,也就是说此时线程正在就绪队列中排队等候得到CPU资源。例如:t1.start();

运行(running):线程获得CPU资源正在执行任务(run()方法),此时除非此线程自动放弃CPU资源或者有优先级更高的线程进入,线程将一直运行到结束。

死亡(dead):当线程执行完毕或被其它线程杀死,线程就进入死亡状态,这时线程不可能再进入就绪状态等待执行。

堵塞(blocked):由于某种原因导致正在运行的线程让出CPU并暂停自己的执行,即进入堵塞状态。

6、线程间的关系?

某线程a 中启动另外一个线程 t,那么我们称线程 t是线程a 的一个子线程,而线程a 是线程t 的父线程。

最典型的就是我们在main方法中启动一个线程去执行。其中main方法隐含的main线程为父线程。

7、线程API一览:如何启动、停止、暂停、恢复线程?

(1)start() 使线程处于就绪状态,Java虚拟机会调用该线程的run方法;

(2)stop() 停止线程,已过时,存在不安全性,原因如下:

一是可能请理性的工作得不得完成;

二是可能对锁定的对象进行“解锁”,导致数据不同步不一致的情况。

推荐使用 interrupt() +抛异常中断线程。

(3)yield() 线程礼让,放弃当前线程的CPU资源。放弃时间不确认,也有可能刚刚放弃又获得CPU资源。

(4)t.join() 正在执行t.join()语句的线程等待t线程运行完终止。

8、synchronized关键字用法

一原子性(互斥性):实现多线程的同步机制,使得锁内代码的运行必需先获得对应的锁,运行完后自动释放对应的锁。

二内存可见性:在同一锁情况下,synchronized锁内代码保证变量的可见性。

三可重入性:当一个线程获取一个对象的锁,再次请求该对象的锁时是可以再次获取该对象的锁的。

如果在synchronized锁内发生异常,锁会被释放。

总结:

(1)synchronized方法与synchronized(this) 代码块锁定的都是当前对象,不同的只是同步代码的范围

(2)synchronized (非this对象x) 将对象x本身作为“对象监视器”:

a、多个线程同时执行 synchronized(x) 代码块,呈现同步效果。

b、当其他线程同时执行对象x里面的 synchronized方法时,呈现同步效果。

c、当其他线程同时执行对象x里面的 synchronized(this)方法时,呈现同步效果。(3)静态synchronized方法与synchronized(calss)代码块锁定的都是Class锁。Class 锁与对象锁不是同一个锁,两者同时使用情况可能呈异步效果。

(4)尽量不使用synchronized(string),是因为string的实际锁为string的常量池对象,多个值相同的string对象可能持有同一个锁。

9、ReentrantLock的使用

一个简单的示例:

private java.util.concurrent.locks.Lock lock = new ReentrantLock();

public void method() {

try {

lock.lock();

//获取到锁lock,同步块

} finally {

lock.unlock();//释放锁lock

}

}

ReentrantLock 比 synchronized 功能更强大,主要体现:

(1)ReentrantLock 具有公平策略的选择。

(2)ReentrantLock 可以在获取锁的时候,可有条件性地获取,可以设置等待时间,很有效地避免死锁。

如 tryLock() 和tryLock(long timeout, TimeUnit unit)

(3)ReentrantLock 可以获取锁的各种信息,用于监控锁的各种状态。

(4)ReentrantLock 可以灵活实现多路通知,即Condition的运用。

10、线程间的通信方式

线程间通信的方式主要为共享内存、线程同步。

线程同步除了synchronized互斥同步外,也可以使用wait/notify实现等待、通知的机制。(1)wait/notify属于Object类的方法,但wait和notify方法调用,必须获取对象的对象级别锁,即synchronized同步方法或同步块中使用。

(2)wait()方法:在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,或者其他某个线程中断当前线程,导致当前线程一直阻塞等待。等同wait(0)方法。