Java多线程学习笔记(适合对多线程有一定理解又认为理解不够全面的人阅读查漏补缺,适合面试前看)

start()方法才是正确的线程启动方式,run()方法仅仅是普通的方法调用。(常见面试题)


Thread和Runnable的关系:Thread 类本身实现了 Runnable 接口,并且持有 run 方法,但 Thread 类的 run 方法主体是空的,Thread 类的 run 方法通常是由子类的 run 方法重写。


实现Runnable接口比继承Thread类所具有的优势:

(1)适合多个相同的程序代码的线程去处理同一个资源。

(2)可以避免Java中的单继承的限制。

(3)增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。

(4)线程池只能放入实现Runable或Callable类线程,不能直接放入继承Thread的类。


线程安全概念:当多个线程访问某一个类(对象或方法)时,这个类始终能表现出正确的行为,那么这个类(对象或方法)就是线程安全的。
线程安全的代码会通过同步机制(比如加锁)保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。
加锁机制常见的如:Synchronized


一个对象有一把锁,如果要让所有对象共用一个锁,给方法加上static即可。因为用 static 修改的方法或者变量,在该类的所有对象是具有相同的引用的。


可重入锁:即该锁可以被对象自己重新获取自己的内部锁,避免出现死锁。


synchronized ()中的括号要传入同一个对象才有意义,可以传入的对象例如有;this(多个线程中this不一定是同一个对象)、字节码对象(一定是同一个对象,内存中只有一个字节码对象,例如传入String.class)、局部对象等。


实现多线程的方式有几种?
一般来说是两种,一种是继承Thread类,另外一种是实现Runable接口。说得全面点还有一种是实现Callable接口,并与Future、线程池结合使用。


wait()与sleep()区别

  1. 对于sleep()方法,该方法是属于Thread类中的。而wait()方法,则是属于Object类中的。
  2. sleep()方法导致了程序暂停执行指定的时间,让出cpu给其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。
  3. 在调用sleep()方法的过程中,线程不会释放对象锁。
  4. 而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。

volatile关键字可以保证可见性和有序性不能保证原子性


欢迎评论点赞收藏!您的支持是我创作的动力!感谢支持!

猜你喜欢

转载自blog.csdn.net/ldkjsdty/article/details/89376329