• Java 中传统多线程


    @

    Java 中传统多线程

    线程初识

    线程的概念

    当代操作系统中,可以独立并发执行的基本单元
    轻量:占用系统资源极少
    独立:操作系统可以独立调度和分派的基本单元
    共享:共享进程中的资源

    实现线程

    继承Thread类,重写run方法
    实现Runnable接口,实现run方法

    package com.xc.test.threadtest;
    
    public class ThreadDemo {
        public static void main(String[] args) throws InterruptedException {
            Thread threadA = new ThreadA();
            threadA.setName("ThreadA");
            threadA.start();
    
            ThreadB threadB = new ThreadB();
            Thread thread = new Thread(threadB);
            thread.start();
    
            while (true) {
                Thread.sleep(1000);
                System.out.println(3);
            }
    
        }
    }
    
    class ThreadA extends Thread {
        public void run() {
            while (true) {
                System.out.println(this.getName() + ":" + 2);
            }
        }
    }
    
    class ThreadB implements Runnable {
        public void run() {
            while (true) {
                System.out.println(4);
            }
    
        }
    }
    

    线程的生命周期

    新建:线程刚刚创建完毕
    可运行:启动线程后
    运行:操作系统调度
    阻塞/等待:等待某种资源或时间片到
    消亡:退出run方法

    常用API

    类方法:针对当前运行线程
    currentThread:获取当前运行线程的引用
    yield:使得当前运行线程放弃当前时间片
    sleep:使得当前运行线程休眠多少时间(单位是毫秒)

    实例方法:针对指定线程
    start:启动线程
    setP:设置/获取线程优先级
    setName/getName:设置/获取线程名称
    setD:设置/获取线程的幽灵状态

    线程同步

    多线程共享数据的问题

    多个线程并发访问同一个数据时,容易发生数据状态不稳定
    使用锁机制完成线程同步(同-协同,步-调用顺序)

    package com.xc.test.threadtest;
    
    public class SysDemo {
        public static void main(String[] args) {
            Data data = new Data();
            new ThreadC(data).start();
            new ThreadC(data).start();
        }
    }
    
    class Data {
        int i;
    
        public void process() {
            System.out.println("Before:" + i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            i++;
            System.out.println("After:" + i);
        }
    }
    
    class ThreadC extends Thread {
        Data data;
    
        public ThreadC(Data data) {
            this.data = data;
        }
    
        public void run() {
            super.run();
            while (true) {
                data.process();
            }
        }
    }
    
    Before:0
    Before:0
    After:1
    After:2
    Before:2
    Before:2
    After:3
    Before:4
    After:4
    

    线程同步及实现机制

    每个类一把锁,每个对象一把锁
    只有获取锁的线程可以进入同步区域

    class Data {
        int i;
    
        public void process() {
            synchronized (this) {//对象锁(任意对象),同步块
                System.out.println("Before:" + i);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                }
                i++;
                System.out.println("After:" + i);
            }
        }
    }
    
    class Data {
        int i;
    
        public synchronized void process() {//对象锁(当前对象),同步方法
            System.out.println("Before:" + i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
            }
            i++;
            System.out.println("After:" + i);
        }
    }
    
    Before:0
    After:1
    Before:1
    After:2
    Before:2
    After:3
    Before:3
    After:4
    

    线程间通讯

    线程间通讯模型

    wait:使当前线程进入指定对象的等待池
    notify:从指定对象等待池中唤醒一个等待线程
    notifyAll:从指定对象等待池中唤醒全部等待线程
    只有获得该对象的锁后才可以调用上述方法

    线程中通讯的实现

    生产者:synchronized(obj){...;obj.notifyAll()}
    消费者:synchronized(obj){obj.wait(),...;}

    package com.xc.test.threadtest;
    
    public class WnDemo {
        public static void main(String[] args) {
            Data2 data2 = new Data2();
            new Producer(data2).start();
            new Consumer(data2).start();
        }
    }
    
    class Data2 {
        int i;
    
        public void add() {
            synchronized (this) {
                i++;
                if (i % 5 == 0) {
                    notifyAll();
                }
            }
        }
    
        public void sub() {
            synchronized (this) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                }
            }
            System.out.println("Before:" + i);
            i++;
            System.out.println("After:" + i);
        }
    }
    
    class Consumer extends Thread {
        Data2 data;
    
        public Consumer(Data2 data) {
            this.data = data;
        }
    
        public void run() {
            while (true) {
                while (true) {
                    data.sub();
                }
            }
        }
    }
    
    class Producer extends Thread {
        Data2 data;
    
        public Producer(Data2 data) {
            this.data = data;
        }
    
        public void run() {
            while (true) {
                while (true) {
                    data.add();
                }
            }
        }
    }
    
  • 相关阅读:
    浅谈异或运算^的作用
    牛客网剑指offer第40题——数组中只出现一次的数字(浅谈位运算的妙用)
    归并排序——一文吃透归并和递归的思想和完整过程!(没看懂请留言)
    深入分析二分查找及其变体
    vector构造函数的学习
    牛客网剑指offer第34题——找到第一个只出现一次的字符
    牛客网剑指offer第27题——求字符串的全排列
    牛客网剑指offer第20题——定义栈的数据结构
    C++重载运算简介
    Leetcode中字符串总结
  • 原文地址:https://www.cnblogs.com/ooo0/p/10786500.html
Copyright © 2020-2023  润新知