黑马程序员_多线程

进程
进程是一个正在执行中的程序。每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元。

线程
就是进程中的一个独立的控制单元,线程在控制着进程的执行。一个进程至少有一个线程。

jvm启动时,会有一个进程java.exe。该进程中至少有一个线程负责java程序的执行。
而且这个线程运行的代码存在于main方法中,该线程称之为主线程。
其实更细节的说明jvm,jvm启动不止一个线程,还有负责垃圾回收机制的线程。

创建线程的两种方式
继承Thread

Java代码 复制代码 收藏代码
  1. //继承Thread创建线程
  2. class MyThread extends Thread
  3. {
  4. public void run()
  5. {}
  6. }
  7. //开启线程
  8. new MyThread().start();



实现Runnable接口

Java代码 复制代码 收藏代码
  1. //实现Runnable接口
  2. class ImplRunnable extends Runnable
  3. {
  4. public void run()
  5. {
  6. }
  7. }
  8. //开启线程
  9. new Thread(new ImplRunnable).start();



多线程的安全问题
当多个线程在访问同一个共享数据时,会产生安全隐患,一个线程对数据访问还没有结束,另一个线程就开始访问共享数据,导致共享数据错误。

解决办法
对多个线程访问同一个共享数据,只能让一个线程访问完毕后,其他线程在访问,在线程访问时其他线程不允许访问。
java对于多线程的安全问题提供了专业的解决方式,同步代码块。

同步代码块

Java代码 复制代码 收藏代码
  1. synchronized(对象)
  2. {
  3. //需要被同步的代码;
  4. }


对象如同同步锁,持有锁的线程可以在同步中执行。
典型例子:毕向东老师说的,火车上的卫生间。

同步的前提
1.必须要有两个或者两个以上线程。
2.必须是多个线程使用同一个锁(类的class文件对象在内存中唯一的,唯一锁)
必须保证同步中能有一个线程在运行

同步的好处和弊端
同步的好处:解决了多线程的安全问题
同步的弊端:多个线程需要判断锁,较为消耗资源。

如何查找安全问题
1.明确哪些代码是多线程运行代码
2.明确共享数据
3.明确多线程运行代码中哪些语句是操作共享数据的

同步的两种形式
1.同步代码块(对象锁)
2.同步函数(this对象锁)
静态函数的函数锁是class,因为静态函数不可以定义this,它使用的是该方法所在类的字节码对象,静态进内存时,内存中没有本类对象,但是一定有该类对于的字节码文件对象类名.class它的类型是Class。

死锁
同步嵌套同步,而锁却不同,例如同步A需要A锁,同步B需要B锁,一个线程持有A锁,另一个线程持有B锁,A同步块要进入B同步块,同时B同步要进入A同步块,可能都没有释放所,就会出现死锁,程序停止那里不动了。

Java代码 复制代码 收藏代码
  1. /*
  2. 实现Runnable的Test类
  3. */
  4. class Test implements Runnable
  5. {
  6. private boolean flag;
  7. Test(boolean flag)
  8. {
  9. this.flag = flag;
  10. }
  11. public void run()
  12. {
  13. if(flag)//如果true执行if的同步代码块
  14. {
  15. synchronized(MyLock.locka)
  16. {
  17. System.out.println("if...locka");
  18. synchronized(MyLock.lockb)
  19. {
  20. System.out.println("if...lockb");
  21. }
  22. }
  23. }
  24. else//如果false执行else中的同步代码块
  25. {
  26. synchronized(MyLock.locka)
  27. {
  28. System.out.println("else...locka");
  29. synchronized(MyLock.lockb)
  30. {
  31. System.out.println("else...lockb");
  32. }
  33. }
  34. }
  35. }
  36. }
  37. /*
  38. 要用到对象锁locka和lockb
  39. */
  40. class MyLock
  41. {
  42. static Object locka = new Object();
  43. static Object lockb = new Object();
  44. }
  45. /*
  46. 死锁测试
  47. */
  48. class DeadLockTest
  49. {
  50. public static void main(String[] args)
  51. {
  52. //开启两个线程让他们争夺cpu执行权,查看可能出现的死锁情况
  53. Thread t1 = new Thread(new Test(true));
  54. Thread t2 = new Thread(new Test(false));
  55. t1.start();
  56. t2.start();
  57. }
  58. }


原文地址:https://www.cnblogs.com/bjanzhuo/p/3576027.html