栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java多线程笔记

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java多线程笔记

基础

Thread类:Java语言通用线程类,其内部用空的run()方法,创建新的线程需要重新run方法,否则不做任何事

线程的启动:调用Thread派生类对象的start()方法,如果直接调用方法,则run方法会同步执行

java实现多线程的两种方法:

  1. 派生Thread类

    class T1 extends Thread {
        // 重写Thread run方法
        run () {
            // 编写线程任务代码
        }
    }
    T1 t1 = new T1(); // 创建一个线程对象
    t1.start() // 通过start()方法即可执行线程run方法
    
  2. 实现Runable接口,解决Thread类无法进行多继承的问题

    class T implements Runnable {
        // 重写run方法
        run () {
            // 编写线程任务代码
        }
    }
    T t = new T(); // 实例化一个Runable对象
    Thread t2 = new Thread(t); // 通过Thread类构造方法 创建线程对象
    t2.start(); // 通过线程对象的start方法开启线程
    
线程常见方法:
// 状态转变方法
start(); // 开始执行线程
sleep(long); // 睡眠一段时间自动唤醒,毫秒
sleep(long, int); // 睡眠一段时间自动唤醒,精确到纳秒 time = ms + ns
wait(); // 进入阻塞状态 等待
notify(); // 唤醒在此对象监视器上等待的线程  如果不知道唤醒哪一个线程 则最好使用notifyAll
notifyAll(); // 唤醒在此对象监视器上等待的多个线程
yield(); // 放弃执行
// 不建议使用的状态转变方法,容易造成死锁
stop(); // 关闭线程,释放当前线程的所有对象锁
destroy(); // 关闭线程,不释放对象锁
suspend(); // 挂起执行 可用sleep代替
resume(); // 恢复执行 可用notify代替
// 等待其他线程
isAlive(); // 判断此线程是否处于运行状态,可用于同步
join(); // 如t1.join(),阻塞当前运行此方法的线程,等待t1线程执行结束后,当前线程才执行
// 设置优先级
setPriority(); // 设置优先级,优先级高的线程获取CPU资源的可能性更大 1-10
线程同步:
  1. 多线程并行存在的问题:

    假设有两个线程T1,t2进行售票,t1查找数据库,发现火车票T可以出售,所以准备出售T,此时计算机系统切换到t2执行,t2发现火车票T可以出售,因此出售了T,系统再次切换回t1时,t1又会将火车票T出售,这样会导致出错。

  2. synchronized关键字

    java提供了锁的机制,原理是每个线程进入同步代码之前,必须获得锁,否则不能进入。这样就解决了多个线程竞争共享代码的情况。java中锁机制的实现方法是在共享代码之前加入synchronized关键字。

    java有一个同步模型监视器,为每个具有同步代码的对象准备唯一的一把锁,得到锁的线程可以进入同步代码,其他线程只能在外等待。

    如果获得锁的线程调用wait()方法进入阻塞状态,其他线程可以使用notify()方法唤醒该线程

  3. 同步格式

    // 同步方法
    public synchronized void method() {
        ...
    }
    // 同步代码快
    synchronized(obj) { // 需获得obj对象的锁才能进入,obj作用域不同,控制情况不同
        ...//obj可以使用this
    }
    
    
线程通信:
  1. 场景:消费者和生产者

    假设寒冷的冬天,人们在在路边摊买手抓饼,如果老板做出的饼太多没有卖出会凉掉,所以他只做一个饼,等一个饼卖掉了,才会又做一个饼。如果有做好的饼,路人会直接买,如果没有,路人会告诉老板他需要做饼,然后等等老板做好,老板做好了会告诉路人可以买饼了。

  2. 关键代码

    // 同步方法同一个时刻只能一个线程方法
    private synchronized void buyFood () {
        if (Thread.currentThread().getName().equals("T1")){ // 生产者线程
            if (food == 0) {
                food ++;
                // 输出: "做了一个手抓饼,现在有" + food;
                notify(); // 做好饼了通知路人
            } else {
                wait(); // 如果还有饼 需要卖出之后再做
            }
        } else {  // 消费者线程
            if (food > 0) {
                food --;
                // 输出: "买一个手抓饼,还剩" + food;
            } else {
                notify(); // 没有饼了通知老板做饼
                wait(); // 等待老板做饼
            }
        }
    }
    
    死锁

    ​ 为了保证数据安全使用synchronized关键字实现对象锁的同步机制,但是如果一个线程拥有了A的锁,这时候需要B的锁,而另一个线程拥有B的锁,这时候需要A的锁,这样就出现了死锁的现象,因为两个线程都在等待对象释放锁,所以两个线程会无休止地等待下去,导致程序无法继续往下运行。

    // 死锁示例关键代码:
    private void accessA () {
        flag = false; // 设置标志位,使另一个线程走进另一个分支
        synchronized (A) {
            // 输出:Thread.currentThread().getName() + "已经获得A的锁";
            Thread.sleep(1000); // 休眠  确保另一个线程获得B的锁
            // 输出:Thread.currentThread().getName() + "准备获取B的锁...";
            synchronized (B) {
                // 输出:Thread.currentThread().getName() + "已经获得B的锁";
            }
        }
    }
    private void accessB () {
        flag = true; // 设置标志位,使另一个线程走进另一个分支
        synchronized (B) {
            // 输出:Thread.currentThread().getName() + "已经获得B的锁";
            Thread.sleep(1000); // 休眠  确保另一个线程获得A的锁
            // 输出:Thread.currentThread().getName() + "准备获取A的锁...";
            synchronized (A) {
                // 输出:Thread.currentThread().getName() + "已经获得A的锁";
            }
        }
    }
    private class T extends Thread {
        @Override
        public void run() {
            if (flag) {
                accessA();
            } else {
                accessB();
            }
        }
    }
    

    控制台输出结果:

    ​ T1已经获得A的锁
    ​ T2已经获得B的锁
    ​ T2准备获取A的锁…
    ​ T1准备获取B的锁…

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/328994.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号