• Java多线程总结


    Java多线程

    在Java的JDK开发包中,已经自带了对多线程技术的支持,可以很方便地进行多线程编程。实现多线程编程的方式有两种,一种是继承 Thread 类,另一种是实现 Runnable 接口。使用继承 Thread 类创建线程,最大的局限就是不能多继承,所以为了支持多继承,完全可以实现 Runnable 接口的方式。

    继承 Thread 类

    // 继承  Thread类 重写 run()方法
    public class ThreadDemo1 extends Thread {
    
        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                System.out.println(Thread.currentThread().getName() + "   ---> " + i);
            }
        }
    
        public static void main(String[] args) {
    
            ThreadDemo1 t1 = new ThreadDemo1();
    
            // 通过 start()开启一个线程
            t1.start();
            for (int i = 0; i < 20; i++) {
                System.out.println(Thread.currentThread().getName() + "   ---> " + i);
            }
        }
    }

    2.实现 Runnable 接口

    // 通过实现 Runnable接口,实现 run()方法
    public class ThreadDemo2 implements Runnable {
    
        @Override
        public void run() {
    
            for (int i = 0; i < 20; i++) {
                System.out.println(Thread.currentThread().getName() + "   ---> " + i);
            }
        }
    
        public static void main(String[] args) {
    
    
            ThreadDemo2 td2 = new ThreadDemo2();
    
            // 通过 Thread类的构造器,传入 Runnale类型的对象
            Thread t1 =
                new Thread(td2);
    
            // 调用 Thread的 start()开启线程
            t1.start();
    
            for (int i = 0; i < 20; i++) {
                System.out.println(Thread.currentThread().getName() + "   ---> " + i);
            }
        }
    }

    Thread.java 类中的start()方法通知“线程规划器”此线程已经准备就绪,等待调用线程对象的run()方法。这个过程其实就是让系统安排一个时间来调用 Thread 中的 run() 方法,也就是使线程得到运行,多线程是异步的,线程在代码中启动的顺序不是线程被调用的顺序。

    当时使用多个线程操作同一个变量时,就会产生 线程安全问题。

    为解决这样的数据错误问题。需要使用 synchronized 关键字

    synchronized() {将要被同步的代码写在打括号中} 为同步代码块

    while (true) {
        // 同步代码块
        synchronized (this) {
            // 唤醒所有正在等待的线程
            //  notifyAll();
            if (ticket > 0) {
    
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
                System.out.println(Thread.currentThread().getName() + " ---> " + ticket + " 号票 已卖出 ,还剩余 " + --ticket + " 票");
                try {
                    // 当前线程等待
                    //  wait();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                // 跳出循环
                break;
            }
        }

    synchronized 可以修饰代码块,也可以修饰在方法上,public 后面

    @Override
    public synchronized void run() {
        while (true) {
            // 对要同步的 代码块 加锁
            //            synchronized (this) {
            // 唤醒一个线程
            notify();
            if (num <= 100) {
                try {
                    // 线程睡眠 10毫秒
                    Thread.sleep(30);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "  -->  " + num);
                num++;
                try {
                    // 当前线程打印完以后等待,等待被下一个线程唤醒
                    wait();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                break;
                //                }
            }
        }
    }

    多线程是异步的,线程在代码中启动的顺序不是线程被调用的顺序。

    对于如何设置将线程同步执行。即一个一个的按照顺序执行?

    需要使用Object的APi中的一些方法。

    • wait():等待,如果线程执行了wait方法,那么该线程会进入等待的状态,等待状态下的线程必须要被其他线程调用notify()方法才能唤醒。

    • notify():唤醒,唤醒线程池等待线程其中的一个。

    • notifyAll():唤醒线程池所有等待线程。

    注意!

    wait与notify方法要注意的事项:

    1. wait方法与notify方法是属于Object对象的。

    1. wait方法与notify方法必须要在同步代码块或者是同步函数中才能使用。

    1. wait方法与notify方法必须要由所对象调用。


     


    多线程方法API

    1、currentThread()方法

    currentThread()方法可返回代码段正在被哪个线程调用的信息。

    Thread.currentThread().getName()

    2、isAlive()方法

    方法isAlive()的功能是判断当前的线程是否处于活动状态。

    thread.isAlive();

    3、sleep()方法

    方法sleep()的作用是在指定的毫秒数内让当前"正在执行的线程"休眠(暂停执行)。这个"正在执行的线程"是指this.currentThread()返回的线程。

    Thread.sleep()

    4、getId()方法

    getId()方法的作用是取得线程的唯一标识。

    thread.getId()

  • 相关阅读:
    部分数据文件损坏的修复处理示例.sql
    使用UPDATE进行编号重排的处理示例.sql
    DNS Prefetching 技术引入及实现方法
    查找指定节点的所有子节点的示例函数.sql
    特殊的交叉报表处理示例.sql
    定时备份FTP+Mysql到云服务器
    cPanel下安装GodaddySSL教程
    移动节点处理的通用存储过程.sql
    应用程序角色使用示例.sql
    文件及文件组备份与还原示例.sql
  • 原文地址:https://www.cnblogs.com/mt-blog/p/13346639.html
Copyright © 2020-2023  润新知