• 线程API


    sleep阻塞

    线程提供了一个静态方法:

    • static void sleep(long ms)
    • 使运行该方法的线程进入阻塞状态指定的毫秒,超时后线程会自动回到RUNNABLE状态等待再次获取时间片并发运行.
    1. public class SleepDemo {
    2.    public static void main(String[] args) {
    3.        System.out.println("程序开始了!");
    4.        try {
    5.            Thread.sleep(5000);//主线程阻塞5秒钟
    6.        } catch (InterruptedException e) {
    7.            e.printStackTrace();
    8.        }
    9.        System.out.println("程序结束了!");
    10.    }
    11. }

    sleep方法处理异常:InterruptedException.

    当一个线程调用sleep方法处于睡眠阻塞的过程中,该线程的interrupt()方法被调用时,sleep方法会抛出该异常从而打断睡眠阻塞.

     

    守护线程与普通线程的区别:守护线程是通过普通线程调用setDaemon(true)设置而来的

    主要区别体现在当java进程中所有的普通线程都结束时进程会结束,在结束前会杀死所有还在运行的守护线程。

    1. public class DaemonThreadDemo {
    2.    public static void main(String[] args) {
    3.        Thread demo1 = new Thread(){
    4.            public void run(){
    5.                for(int i=0;i<5;i++){
    6.                    System.out.println("222");
    7.                    try {
    8.                        Thread.sleep(1000);
    9.                   } catch (InterruptedException e) {
    10.                   }
    11.               }
    12.                System.out.println("111");
    13.           }
    14.       };
    15.        Thread demo2 = new Thread(){
    16.            public void run(){
    17.                while(true){
    18.                    System.out.println("333");
    19.                    try {
    20.                        Thread.sleep(1000);
    21.                   } catch (InterruptedException e) {
    22.                   }
    23.               }
    24.           }
    25.       };
    26.        demo1.start();
    27.        demo2.setDaemon(true);//设置守护线程必须在线程启动前进行
    28.        demo2.start();
    29.   }
    30. }

    重点:多线程并发安全问题

    • 什么是多线程并发安全问题:
      当多个线程并发操作同一临界资源,由于线程切换时机不确定,导致执行顺序出现混乱。
      解决办法:
      将并发操作改为同步操作就可有效的解决多线程并发安全问题
    • 同步与异步的概念:同步和异步都是说的多线程的执行方式。
      多线程各自执行各自的就是异步执行,而多线程执行出现了先后顺序进行就是同步执行
      1. public class SyncDemo {
      2. public static void main(String[] args) {
      3. Table table = new Table();
      4. Thread t1 = new Thread(){
      5. public void run(){
      6. while(true){
      7. int bean = table.getBean();
      8. Thread.yield();
      9. System.out.println(getName()+":"+bean);
      10. }
      11. }
      12. };
      13. Thread t2 = new Thread(){
      14. public void run(){
      15. while(true){
      16. int bean = table.getBean();
      17. /*
      18. static void yield()
      19. 线程提供的这个静态方法作用是让执行该方法的线程
      20. 主动放弃本次时间片。
      21. 这里使用它的目的是模拟执行到这里CPU没有时间了,发生
      22. 线程切换,来看并发安全问题的产生。
      23. */
      24. Thread.yield();
      25. System.out.println(getName()+":"+bean);
      26. }
      27. }
      28. };
      29. t1.start();
      30. t2.start();
      31. }
      32. }
      33. class Table{
      34. private int beans = 20;//桌子上有20个豆子
      35. public int getBean(){
      36. if(beans==0){
      37. throw new RuntimeException("没有豆子了!");
      38. }
      39. Thread.yield();
      40. return beans--;
      41. }
      42. }

      synchronized的两种用法

    • 1.直接在方法上声明,此时该方法称为同步方法,同步方法同时只能被一个线程执行
      2.同步块,推荐使用。同步块可以更准确的控制需要同步执行的代码片段。
      有效的缩小同步范围可以在保证并发安全的前提下提高并发效率
      1. public class SyncDemo {
      2. public static void main(String[] args) {
      3. Table table = new Table();
      4. Thread t1 = new Thread(){
      5. public void run(){
      6. while(true){
      7. int bean = table.getBean();
      8. Thread.yield();
      9. System.out.println(getName()+":"+bean);
      10. }
      11. }
      12. };
      13. Thread t2 = new Thread(){
      14. public void run(){
      15. while(true){
      16. int bean = table.getBean();
      17. /*
      18. static void yield()
      19. 线程提供的这个静态方法作用是让执行该方法的线程
      20. 主动放弃本次时间片。
      21. 这里使用它的目的是模拟执行到这里CPU没有时间了,发生
      22. 线程切换,来看并发安全问题的产生。
      23. */
      24. Thread.yield();
      25. System.out.println(getName()+":"+bean);
      26. }
      27. }
      28. };
      29. t1.start();
      30. t2.start();
      31. }
      32. }
      33. class Table{
      34. private int beans = 20;//桌子上有20个豆子
      35. /**
      36. * 当一个方法使用synchronized修饰后,这个方法称为同步方法,多个线程不能
      37. * 同时执行该方法。
      38. * 将多个线程并发操作临界资源的过程改为同步操作就可以有效的解决多线程并发
      39. * 安全问题。
      40. * 相当于让多个线程从原来的抢着操作改为排队操作。
      41. */
      42. public synchronized int getBean(){
      43. if(beans==0){
      44. throw new RuntimeException("没有豆子了!");
      45. }
      46. Thread.yield();
      47. return beans--;
      48. }
      49. }

    • 同步监视器对象的选取:
      对于同步的成员方法而言,同步监视器对象不可指定,只能是this
      对于同步的静态方法而言,同步监视器对象也不可指定,只能是类对象
      对于同步块而言,需要自行指定同步监视器对象,选取原则:
      1.必须是引用类型
      2.多个需要同步执行该同步块的线程看到的该对象必须是同一个
    • 互斥性
      当使用多个synchronized修饰了多个代码片段,并且指定的同步监视器都是同一个对象时,这些代码片段就是互斥的,多个线程不能同时在这些代码片段上执行。
    1. public class SyncDemo4 {
    2.    public static void main(String[] args) {
    3.        Foo foo = new Foo();
    4.        Thread t1 = new Thread(){
    5.            public void run(){
    6.                foo.methodA();
    7.           }
    8.       };
    9.        Thread t2 = new Thread(){
    10.            public void run(){
    11.                foo.methodB();
    12.           }
    13.       };
    14.        t1.start();
    15.        t2.start();
    16.   }
    17. }
    18. class Foo{
    19.    public synchronized void methodA(){
    20.        Thread t = Thread.currentThread();
    21.        try {
    22.            System.out.println(t.getName()+":正在执行A方法...");
    23.            Thread.sleep(5000);
    24.            System.out.println(t.getName()+":执行A方法完毕!");
    25.       } catch (InterruptedException e) {
    26.            e.printStackTrace();
    27.       }
    28.   }
    29.    public synchronized void methodB(){
    30.        Thread t = Thread.currentThread();
    31.        try {
    32.            System.out.println(t.getName()+":正在执行B方法...");
    33.            Thread.sleep(5000);
    34.            System.out.println(t.getName()+":执行B方法完毕!");
    35.       } catch (InterruptedException e) {
    36.            e.printStackTrace();
    37.       }
    38.   }
    39. }

     

  • 相关阅读:
    Session会话追踪的实现机制
    JCMSuite应用-高功率半导体激光器
    电商美工设计有哪些基本规范原则 优漫动游
    疫情可视化part2
    谷歌浏览器修改背景色
    渲染引擎什么情况下才会为特定的节点创建新的图层
    vue后台项目菜单路由不匹配或者路径错误,添加默认404页面的方法
    在两台CentOS 7服务器上部署MinIO集群。
    Linux学习笔记——Makefile的使用
    【软考】8.1 程序语言基本概念-成分-函数
  • 原文地址:https://blog.csdn.net/m0_51041464/article/details/126233504