首页 > 系统相关 >Java进程(基础)

Java进程(基础)

时间:2023-05-17 09:34:02浏览次数:38  
标签:Java Thread void 基础 start 线程 进程 new public

基本概念

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

标签:Java,Thread,void,基础,start,线程,进程,new,public
From: https://www.cnblogs.com/cxy8/p/17389993.html

相关文章

  • 一个程序设计业务中,如果需要这个表数据对应3种业务,但是唯独其中一种要多几个字段去展
    作为一个AI助手,我可以为您提供一些设计思路,但是最终的决定应该基于具体场景和业务需求。一种解决方案是在原表基础上新增字段。这种方法简单快捷,可以避免复杂的表关联,但是会使得表结构变得臃肿,不利于维护和拓展。如果这个表在后续的业务中还需要扩展字段,就会更加困难。另一种解......
  • Java-Day-22( 线程一:相关概念 + 继承 Thread 类 + 实现 Runnable 接口 + JConsole 监控
    Java-Day-22线程相关概念程序:是为完成特定任务、用某种语言编写的一组指令的集合(就是平常所写代码)进程:运行中的程序,例如,打开一个软件就启动一个进程,操作系统就会给每个启动的软件分配一新的内存(活动进程占用的物理内存)空间进程是程序的一次执行过程,或是正在运......
  • Python: 结合多进程和 Asyncio 以提高性能
    动动发财的小手,点个赞吧!简介多亏了GIL,使用多个线程来执行CPU密集型任务从来都不是一种选择。随着多核CPU的普及,Python提供了一种多处理解决方案来执行CPU密集型任务。但是直到现在,直接使用多进程相关的API还是存在一些问题。在本文开始之前,我们还有一小段代码来帮助演......
  • SSM整合报错:errorCode 1045, state 28000 java.sql.SQLException: Access denied for
    SSM整合报错:errorCode1045,state28000java.sql.SQLException:Accessdeniedforuser简述SSM整合项目配置好环境后,当要对数据库进行操作,加载jdbc.properties数据库配置文件时,出现下面的报错createconnectionSQLException,url:jdbc:mysql://localhost:3306/furn_ssm,......
  • SQL常用的基础语法
    声明        本公众号所有内容,均属微信公众号:开源优测 所有,任何媒体、网站或个人未经授权不得转载、链接、转贴或以其他方式复制发布/发表。已经本公众号协议授权的媒体、网站,在使用时必须注明"稿件来源微信公众号:开源优测",违者本公众号将依法追究责任。SQL常用的语法......
  • MySQL数据基础知识整理—1
     MySQL数据库在学习之前,我们要了解什么是MySQL数据库?MySQL数据库是一个开源的关系型数据库管理系统,我们可以使用SQL(StructuredQueryLanguage)作为开发语言,对数据进行操作,并且,该数据库支持多用户,多线程,多种存储引擎,因此被广泛的应用于Web开发中。    简单来说,MySQL数据库就......
  • Javaweb
    资源无法导出问题<!--在build中配置resources,来防止我们资源导出失败问题--><build>  <resources>    <resource>      <directory>src/main/resources</directory>      <includes>        <include>**/*.properties<......
  • Java设计模式-装饰模式
    简介装饰模式在Java领域是一种常见的设计模式,它能够在不改变对象原有结构的情况下,动态地为对象添加新的功能。它通过封装原有对象,在运行时动态地为对象添加新的行为或者修改原有行为,以扩展对象的功能。这种方式避免了继承的静态特性,让对象的行为可以根据需要进行动态变化。在装......
  • linux 下运行一个java程序
     在linux下,测试一个小程序如果用到自己lib,则在程序目录下建一个lib目录,把相应的jar放进去。test是package名称java-classpath.:lib/*test.TestPing    在linux的后台运行#nohupjava-classpath.:lib/*hkrecdis&#exit......
  • LR操作疑问--基础篇
    在用LR进行并发测试时,经常会出现下载资源超时而产生执行失败的事物,LR有更改超时的时间限制好像最大是1000吧,设置最大值后,进行几十个并发时还是会出现大量失败的事物,通过查询数据库可发现虽然执行失败了但所有并发操作在数据库中都正确执行的相关的动作。 大家在作并发测试时是否会......