Java进程(基础)

news2024/9/20 8:45:02

基本概念

1、进程:程序的执行过程
2、线程:一个进程可以有单个线程也就是我们说的单线程,还可以有多个线程也就是我们说的多线程,

线程

1、当一个类继承了Thread类就可以当成一个线程用
2、我们会重写run方法写上我们自己的业务逻辑
3、run Thread类实现了RUnnable接口,静态代理模式

创建一个线程为什么是start不是直接调用run方法,如果直接调用run方法并没有创建一个线程,而是串行执行,start方法中的start0方法创建一个线程是由本地方法,是由JVM调用的

当一个类他已经继承了其他类,但是我们还想让其作为线程使用的话就可以让其实现Runable接口

package threaduse;

public class Thread01 {
    public static void main(String[] args) {
        Cat cat = new Cat();
        //没有start方法
        //cat.start();
        Thread thread = new Thread(cat);
        thread.start();
    }
}
class Cat implements Runnable
{
    int cnt = 0;
    @Override
    public void run() {
        while(true)
        {
            System.out.println("小狗汪汪叫hi " + (++ cnt) + Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            if(cnt == 10)   break;
        }
    }
}

多个子线程案例

package threaduse;

public class Thread03 {
    public static void main(String[] args) {
        T1 t1 = new T1();
        T2 t2 = new T2();
        Thread thread = new Thread(t1);
        Thread thread1 = new Thread(t2);
        thread1.start();
        thread.start();
    }

}

class T1 implements Runnable
{
    int cnt = 0;
    @Override
    public void run() {
        while(true)
        {
            System.out.println("hello world " + (++cnt));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            if(cnt == 10)   break;
        }
    }
}
class T2 implements Runnable
{
    int cnt = 0;
    @Override
    public void run() {
        while(true)
        {
            System.out.println("hi " + (++cnt));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            if(cnt == 10)   break;
        }
    }
}

模拟售票

package ticket;

//使用多线程模拟三个窗口同时售票
public class SellTicket {
    public static void main(String[] args) {
        SellTicket01 sellTicket01 = new SellTicket01();
        SellTicket01 sellTicket011 = new SellTicket01();
        SellTicket01 sellTicket012 = new SellTicket01();
        sellTicket012.start();
        sellTicket011.start();
        sellTicket01.start();
    }
}

//使用继承Thread
class SellTicket01 extends Thread
{
    private static int num = 100;
    @Override
    public void run() {
        while(true)
        {
            if(num <= 0)
            {
                System.out.println("售票结束...");
                break;
            }
            //休眠50ms
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
            }
            System.out.println("窗口 " + Thread.currentThread().getName() +
                    "售出一张票" + "剩余票数 = " + (-- num));
        }
    }
}

出现问题

2.png
票重复卖
3.png

这里先提出问题后续会解决啦

通知线程退出

package exit_;

public class Thread_Exit {
    public static void main(String[] args) throws InterruptedException {
        T t = new T();
        t.start();
        //如果我们希望main线程去控制t线程的终止,必须可以修改loop->通知方式
        //休眠10s
        Thread.sleep(10 * 1000);
        t.setLoop(false);
    }
}

class T extends Thread
{
    int cnt = 0;

    //设置一个变量
    private boolean loop = true;
    @Override
    public void run() {
        while(loop)
        {
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("T还在运行" + (++ cnt));
        }
    }

    public void setLoop(boolean loop) {
        this.loop = loop;
    }
}

线程中断

线程的常用方法

1、start会调用run方法并且会创建一个新线程而单独调用run方法并不会创建新线程
2、interrupt,中断线程一般用于结束正在休眠的线程
3、sleep线程的休眠
3、现成的优先级
MAX、MIN、NORM

package Method;

import sun.awt.windows.ThemeReader;

public class ThreadMethod01 {
    public static void main(String[] args) throws InterruptedException {
        T t = new T();
        t.setName("阿杜");
        t.setPriority(Thread.MIN_PRIORITY);
        t.start();
        System.out.println(t.getName());
        //主线程打印5个hi,然后就中断子线程的休眠
        for(int i = 1; i <= 5; ++ i)
        {
            Thread.sleep(1000);
            System.out.println("hi" + i);
        }
        t.interrupt();
    }
}

//自定义的线程类
class T extends Thread
{
    @Override
    public void run() {
        while(true)
        {
            for(int i = 0; i < 100; ++ i)
            {
                //Thread.currentThread().getName()获取当前线程的名称
                System.out.println(Thread.currentThread().getName() + "吃包子~~~~~" + i);
            }
            try {
                System.out.println(Thread.currentThread().getName() + "休眠中~~~~~");
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                //InterruptedException捕获到一个中断异常
                System.out.println(Thread.currentThread().getName() + "被 interrupt了");
            }
        }

    }
}

线程插队

yield:线程的礼让,让出cpu让其他线程先执行,让出的时间不确定,所以也不一定能成功让出
join:线程的插队,插队一旦成功,就一定会先执行完插队的进程
join方法调用的是对方的,也就是你想让插队的那个线程的
例题
2.png

package Method;

public class ThreadMethodExercise {
    public static void main(String[] args) throws InterruptedException {
        T3 t3 = new T3();
        Thread thread = new Thread(t3);
        for(int i = 1; i <= 10; ++ i)
        {
            System.out.println("hi " + i);
            if(i == 5)
            {
                thread.start();
                thread.join();
            }
        }
    }
}

class T3 implements Runnable
{
    @Override
    public void run() {
        for(int i = 1; i <= 10; ++ i)
        {
            System.out.println("hello " + i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

1.png

用户线程和守护线程

用户线程:也叫工作线程,当线程的任务执行完或以通知的形式结束
守护线程:一般是为用户线程工作的,当所有用户线程结束守护线程自动结束
常见的守护线程:垃圾回收机制
3.png

package Method;

public class ThreadMethod03 {
    public static void main(String[] args) throws InterruptedException {
        MyDaemonThread myDaemonThread = new MyDaemonThread();
        //我们希望当主线程结束后子线程能自动结束,我们需要将子线程设置为守护线程
        myDaemonThread.setDaemon(true);
        myDaemonThread.start();
        for (int i = 1; i <= 10; ++i)
        {
            System.out.println("阿杜在辛苦的工作");
            Thread.sleep(1000);
        }
    }
}

class MyDaemonThread extends Thread
{
    @Override
    public void run() {
        for(;;)
        {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("阿杜和阿范一直在聊天~~~~~");
        }
    }
}

4.png

线程的七大状态

6.png
5.png

线程同步

在多线程中,对一些敏感数据可能同一时刻只允许一个线程访问,为了保证数据的完整性,任何同一时刻我们都只让一个线程访问
synchronized

package syn;

class SellTicket03 implements Runnable
{
    private static int num = 100;
    private boolean loop = true;
    public synchronized void sell(){
        if(num <= 0)
        {
            System.out.println("售票结束。。。。");
            loop = false;
            return;
        }
        while(loop)
        {
            if(num <= 0)
            {
                System.out.println("售票结束...");
                break;
            }
            //休眠50ms
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
            }
            System.out.println("窗口 " + Thread.currentThread().getName() +
                    "售出一张票" + "剩余票数 = " + (-- num));
        }
    }

    @Override
    public void run() {
       sell();
    }
}
//使用多线程模拟三个窗口同时售票
public class SellTicket {
    public static void main(String[] args) {
        SellTicket03 sellTicket03 = new SellTicket03();
        SellTicket03 sellTicket031 = new SellTicket03();
        Thread thread = new Thread(sellTicket03);
        Thread thread1 = new Thread(sellTicket031);
        thread.start();
        thread1.start();
    }
}

互斥锁

上面的同步机制就是利用了锁,当多个线程运行时,他们先争夺锁,只有获得锁的线程才能执行方法,上面的售卖票利用的就是互斥锁
1、java引入互斥锁的概念是为了保证共享数据的完整性
2、互斥锁,用关键字synchronized修饰时表明该对象在任何同一时刻只能有一个线程访问
3、同步之后因为同一时刻只有一个线程在执行,所以效率自然会降低
4、如果锁加在方法上,如果方法是静态的,锁加在类上,如果方法是非静态的,锁加在当前对象(this)上或则其他对象上(并不是很理解呜呜呜~~~~~)

互斥锁想要起作用,多个线程锁的对象必须是同一个

死锁

双方都需要当前对方所拥有的锁资源

package syn;

public class DeadLock_ {
    public static void main(String[] args) {
        DeadLockDemo deadLockDemo = new DeadLockDemo(false);
        DeadLockDemo deadLockDemo1 = new DeadLockDemo(true);
        deadLockDemo1.start();
        deadLockDemo.start();
    }
}

class DeadLockDemo extends Thread
{
    static Object o1 = new Object();
    static Object o2 = new Object();
    boolean flag;

    public DeadLockDemo(boolean flag) {
        this.flag = flag;
    }

    @Override
    public void run() {
        if(flag)
        {
            synchronized (o1)
            {
                System.out.println(Thread.currentThread().getName() + "进入了o1");
                synchronized (o2)
                {
                    System.out.println(Thread.currentThread().getName() + "进入了o2");
                }
            }
        }else{
            synchronized (o2)
            {
                System.out.println(Thread.currentThread().getName() + "进入了o2");
                synchronized (o1)
                {
                    System.out.println(Thread.currentThread().getName() + "进入了o1");
                }
            }
        }
    }
}

1.png

释放锁

释放锁
2.png
不会释放锁
3.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/536680.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

plsql 安装和连接配置

首先下载plsql 安装&#xff0c; 然后 下载oracle 客户端 配置连接(如果安装了oracle 数据库&#xff0c;可以直接配置数据库则可跳过此步骤),下载后解压(解压密码为1) 然后找到 \instantclient_supper\network\admin 目录创建 tnsnames.ora 文件配置数据库连接 例如配置本地…

pynvme操作流程

步骤一&#xff1a;检查本地windows是否安装ssh 检查方式&#xff1a;windows本地打开windows powershell&#xff0c;输入ssh&#xff0c;若打印usage &#xff1a;ssh等一些信息&#xff0c;则已安装ssh&#xff0c;否则需要安装&#xff0c;安装方式如下&#xff0c;一般系…

Java 基础核心总结

目录 前言 介绍 1、基本语法 2、面向对象编程 3、异常处理 4、集合框架 5、IO 流 6、多线程 专栏地址 前言 Java 是一种广泛使用的程序设计语言&#xff0c;具有跨平台、面向对象、安全性高、灵活性强等特点&#xff0c;广泛应用于企业级应用程序和移动应用程序等领域…

win10锁屏或登录时会自动弹出触摸按键的问题解决办法

本篇文章主要讲解win10锁屏或登录时会自动弹出触摸按键的问题解决方式。 日期:2023年5月17日 作者:任聪聪 问题情况截图 屏幕按键说明 如下截图为屏幕按键 设置路径:设置–>轻松使用–>键盘 说明:见图中右侧第一个选择项即使用屏幕键盘的方法,但这并不是本次我们…

《花雕学AI》35:如何一次性和17个AI聊天机器人交流?ChatALL让你轻松实现

聊天机器人&#xff0c;也称为对话机器人&#xff0c;是一种能够通过自然语言与人类进行交流的人工智能系统。聊天机器人的应用领域非常广泛&#xff0c;从客服、娱乐、教育、医疗、社交等&#xff0c;到科研、商业、政治、军事等&#xff0c;几乎无所不包。随着深度学习和自然…

NXP MCUXPresso - 确定冰沙主板工程需要编译的确切文件集合

文章目录 NXP MCUXPresso - 确定冰沙主板工程需要编译的确切文件集合概述END NXP MCUXPresso - 确定冰沙主板工程需要编译的确切文件集合 概述 在尝试迁移 openpnp - Smoothieware project 从gcc命令行 MRI调试方式 到NXP MCUXpresso工程. 先搭了一个MCUXpresso C工程, MCU选…

别去外包,干了三年,废了....

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

祖传渣屏退休季,五月份高性价比显示器推荐

眼看五月中旬&#xff0c;又快到了电商狂欢 618&#xff0c;不少伙伴开始将升级电脑配置、全新装机提上日程。 趁着这个节骨眼&#xff0c;咱们正好出一期当前各段位值得购买的高性价比显示器推荐。 入门办公 小米 Redmi 1A 主要参数&#xff1a;23.8 英寸、1920*1080 分辨…

java: 无法访问org.springframework.boot.SpringApplication

SpringBoot启动报错&#xff1a; 原因 根据错误提示&#xff0c;可以看出是类文件版本错误导致的。Spring Boot 3.06 是基于 JDK 17 编译的&#xff0c;而我的 JDK 版本低于此&#xff0c;是JDK8版本&#xff0c;所以无法访问该类文件。因此&#xff0c;解决这个问题需要将 JD…

C++类和对象再探

文章目录 const成员再谈构造函数成员变量的定义函数体内赋值初始化列表 隐式类型转换explicitstatic成员 const成员 我们知道在调用类的成员函数时,会有一个默认的this指针且这个this指针时不可以被修改的,例如在日期类中,会有隐式的Date * const this;注意这里默认会在this前…

【Java EE 初阶】JUC常见工具类介绍

目录 1.JUC 1.Callable接口&#xff08;描述线程任务的接口&#xff09; 2.Callable接口和Runnable接口区别 2.Reentrant Lock 1.演示基本方法 2.出现异常&#xff0c;如何确保释放锁 3.创建一个公平锁 4.创建一个读写锁 3.Reentrant Lock和Synchronized的区别 4.原子…

( 动态规划) 509. 斐波那契数 ——【Leetcode每日一题】

❓509. 斐波那契数 难度&#xff1a;简单 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n) F(n - 1) F(…

HTTPS如何防止DNS欺骗?

HTTPS加密可以有效帮助服务器应对DNS欺骗、DNS劫持、ARP攻击等安全威胁。DNS是什么&#xff1f;DNS如何被利用&#xff1f;HTTPS如何防止DNS欺骗&#xff1f; DNS如何工作&#xff1f; 如果您想访问www.example.com&#xff0c;您的浏览器需要找到该特定Web服务器的IP地址。它…

入行3年,月薪不足20K,看来是时候跳一次了.....

写在前面的话 不知不觉已经毕业两年半&#xff0c;工作三年了在同一家公司并未跳槽&#xff0c;今年在合适的契机选择了换一家公司&#xff0c;在这里想总结一下三年的工作经验和这次的面试经验。 我毕业于一个本科院校&#xff0c;二本&#xff0c;学习网络工程出来的。到大…

加拿大访学/博后的子女选择公立学校及办理入学手续详解

访问学者及博士后申请者携子女出国接受国外教育是较普遍的现象。近年来由于美国对CSC资助学者的入境限制&#xff0c;越来越多的申请者将目标定为加拿大等英语发达国家。在咨询中&#xff0c;经常有客户问及加拿大孩子入学问题。为此&#xff0c;知识人网小编就谈谈如何选择公立…

jQuery-层级选择器

<!DOCTYPE HTML> <html> <head> <meta http-equiv"Content-Type" content"text/html; charsetUTF-8"> <title>层级选择器</title> <style type"text/css"> …

如何通过边缘智能网关实现暴雨灾害监测预警

随着夏季来临&#xff0c;我国南方逐渐进入雨季&#xff0c;暴雨灾害也进入到频发阶段&#xff0c;给村镇和城市居民都造成诸多人身和财产损失。针对南方雨季的水灾防治&#xff0c;物联网技术派上大用场&#xff0c;本篇就基于边缘智能网关的数采方案&#xff0c;简单介绍对暴…

圣杯布局实现

是什么&#xff1f; 【圣杯布局是两边固定宽度&#xff0c;中间自适应的三栏布局】 圣杯布局是网页排版布局中的一种常见方式&#xff0c;通常用于具有两个侧边栏和一个中间内容区域的网页设计。 这种布局将整个页面区域分为三个部分&#xff1a;顶部导航栏、左侧边栏、右侧…

IDEA直接请求controller,不用postman请求http接口

generated-requests.http工具用法 第一步&#xff1a;点击下面按钮&#xff0c;HTTP Client 第二步、生成generated-requests.http文件 第三步、更改服务的ip和端口&#xff0c;启动服务 请求实例&#xff1a; 1、post请求&#xff0c;body传参&#xff1a; POST http://loc…

新库上线 | CnOpenData·A股上市公司违规处罚数据

A股上市公司违规处罚数据 一、数据简介 据《上市公司信息披露管理办法》&#xff0c;上市公司作为信息披露义务人&#xff0c;应真实、准确、及时、完整地向市场公开依法及自愿披露的信息。这些公开披露的信息包含但不仅限于公司基本情况、主要会计数据和财务指标、股东持股情…