1、idea的安装

尚硅谷_宋红康_IntelliJIDEA的安装、配置与使用.pdf

2、基本概念:程序、进程、线程

QQ截图20220105154616.png
QQ截图20220105155214.png
QQ截图20220105160151.png


多线程程序的优点:
1. 提高应用程序的响应。对图形化界面更有意义,可增强用户体验。
2. 提高计算机系统CPU的利用率
3. 改善程序结构。将既长又复杂的进程分为多个线程,独立运行,利于理解和修改

何时需要多线程
程序需要同时执行两个或多个任务。
程序需要实现一些需要等待的任务时,如用户输入、文件读写操作、网络操作、搜索等。
需要一些后台运行的程序时。

3、线程的创建和使用

方式一:继承Thread类
1) 定义子类继承Thread类。
2) 子类中重写Thread类中的run方法。 将此线程执行的操作声明在run()中
3) 创建Thread子类对象,即创建了线程对象。
4) 调用线程对象start方法:①启动当前线程,②调用当前现成的run方法。
QQ截图20220105174247.png
注意点:
1、我们不能通过直接调用run()的方式启动线程。
2、一个线程对象只能调用一次start()方法启动线程。

匿名子类调用start方法。

  1. package com.atguigu.java2;
  2. public class ThreadDemo {
  3. public static void main(String[] args) {
  4. /*MyThread1 myThread1 = new MyThread1();
  5. MyThread2 myThread2 = new MyThread2();
  6. myThread1.start();
  7. myThread2.start();*/
  8. new Thread() {
  9. @Override
  10. public void run() {
  11. for (int i = 0; i < 100; i++) {
  12. if (i % 2 == 0) {
  13. System.out.println(Thread.currentThread().getName() + ":" + i);
  14. }
  15. }
  16. }
  17. }.start();
  18. }
  19. }
  20. class MyThread1 extends Thread {
  21. @Override
  22. public void run() {
  23. for (int i = 0; i < 100; i++) {
  24. if (i % 2 == 0) {
  25. System.out.println(Thread.currentThread().getName() + ":" + i);
  26. }
  27. }
  28. }
  29. }
  30. class MyThread2 extends Thread {
  31. @Override
  32. public void run() {
  33. for (int i = 0; i < 100; i++) {
  34. if (i % 2 != 0) {
  35. System.out.println(Thread.currentThread().getName() + ":" + i);
  36. }
  37. }
  38. }
  39. }

  1. package com.atguigu.java2;
  2. /*
  3. 测试Thread中的常用方法
  4. 1、start():启动当前线程;调用当前现成的run()
  5. 2、run();通常需要重写Thread中的此方法,将创建的线程要执行的操作声明在此方法中
  6. 3、currentThread():静态方法,返回执行当前代码的线程
  7. 4、getName():获取当前线程的名字
  8. 5、setName():设置当前线程的名字
  9. 6、yield():释放当前CPU的执行权,
  10. 7、join():在线程的a中调用的join(),此时线程a就进入阻塞状态,直到线程b完全执行完以后,线程a才结束阻塞状态
  11. 8、stop():已过时,当执行此方法时,强制结束当前线程
  12. 9、sleep(long millis):让当前线程睡眠指定的毫秒数。在指定的时间内,当前的线程是阻塞状态
  13. 10、isAlive():判断当前对象是否存活。
  14. */
  15. public class ThreadMethodTest {
  16. public static void main(String[] args) {
  17. HelloThread h1 = new HelloThread("Thread:1");
  18. //h1.setName("线程一");
  19. h1.start();
  20. //给主线程命名
  21. Thread.currentThread().setName("主线程");
  22. for (int i = 0; i < 100; i++) {
  23. if (i % 2 == 0) {
  24. System.out.println(Thread.currentThread().getName() + ":" + i);
  25. }
  26. if (i==20){
  27. try {
  28. h1.join();
  29. } catch (InterruptedException e) {
  30. e.printStackTrace();
  31. }
  32. }
  33. }
  34. System.out.println(h1.isAlive());
  35. }
  36. }
  37. class HelloThread extends Thread {
  38. @Override
  39. public void run() {
  40. for (int i = 0; i < 100; i++) {
  41. if (i % 2 == 0) {
  42. try {
  43. sleep(10);
  44. } catch (InterruptedException e) {
  45. e.printStackTrace();
  46. }
  47. System.out.println(Thread.currentThread().getName() + ":" + i);
  48. }
  49. /* if (i % 20 == 0) {
  50. yield();
  51. }*/
  52. }
  53. }
  54. public HelloThread(String name) {
  55. super(name);
  56. }
  57. }

QQ截图20220105193233.png
QQ截图20220105193348.png

  1. package com.atguigu.java2;
  2. /*
  3. 例子:创建三个c窗口买票,总票数为100章
  4. 存在线程安全
  5. */
  6. class Windows extends Thread{
  7. private static int ticket=100;
  8. @Override
  9. public void run() {
  10. while (true){
  11. if (ticket>0){
  12. System.out.println(getName()+":卖票,票号为:"+ticket);
  13. ticket--;
  14. }else{
  15. break;
  16. }
  17. }
  18. }
  19. }
  20. public class WindowsTest {
  21. public static void main(String[] args) {
  22. Windows t1 = new Windows();
  23. Windows t2 = new Windows();
  24. Windows t3 = new Windows();
  25. t1.setName("窗口1");
  26. t2.setName("窗口2");
  27. t3.setName("窗口3");
  28. t1.start();
  29. t2.start();
  30. t3.start();
  31. }
  32. }

方式二:实现Runnable接口
1) 定义子类,实现Runnable接口。
2) 子类中重写Runnable接口中的run方法。
3) 通过Thread类含参构造器创建线程对象。
4) 将Runnable接口的子类对象作为实际参数传递给Thread类的构造器中。
5) 调用Thread类的start方法:开启线程,调用Runnable子类接口的run方法。

  1. package com.atguigu.java2;
  2. class MThread implements Runnable{
  3. @Override
  4. public void run() {
  5. for (int i = 0; i < 100; i++) {
  6. if (i%2==0){
  7. System.out.println(Thread.currentThread.getName()+":"+i);
  8. }
  9. }
  10. }
  11. }
  12. public class ThreadTest1 {
  13. public static void main(String[] args) {
  14. MThread mThread = new MThread();
  15. Thread t1 = new Thread(mThread);
  16. t1.setName("线程一");
  17. t1.start();
  18. Thread t2 = new Thread(mThread);
  19. t2.setName("线程二");
  20. t2.start();
  21. }
  22. }
  1. package com.atguigu.java2;
  2. //存在线程安全
  3. class Window1 implements Runnable {
  4. private int ticket = 100;
  5. @Override
  6. public void run() {
  7. while (true) {
  8. if (ticket > 0) {
  9. System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);
  10. ticket--;
  11. } else {
  12. break;
  13. }
  14. }
  15. }
  16. }
  17. public class WindowsTest1 {
  18. public static void main(String[] args) {
  19. Window1 w = new Window1();
  20. Thread t1 = new Thread(w);
  21. Thread t2 = new Thread(w);
  22. Thread t3 = new Thread(w);
  23. t1.setName("窗口一");
  24. t2.setName("窗口二");
  25. t3.setName("窗口三");
  26. t1.start();
  27. t2.start();
  28. t3.start();
  29. }
  30. }

比较创建线程的两种方式:
开发中:优先选择:实现Runnable接口的方式
原因:1、实现的方式没有类的单继承性的局限性
2、实现的方式更适合来处理多个线程有共享的情况

相同点:两种方式都需要重写run(),将线程要执行的逻辑声明在run().

尚硅谷宋红康第8章_多线程.pdf