java多线程

进程与线程关系?
进程是所有线程的集合,每一个线程是进程中的一条执行路径。
多线程创建方式?
两种 继承Thread类或者实现Runnable接口
继承Thread类好,还是实现runanble接口好
实现runnable接口好 接口灵活,java只能单继承,可以多实现接口;
比如说,小程序必须继承Applet类,它就不能再继承Thread类了
启动线程是调用run还是start
start是启动线程,调用run只是普通的调用
start就像是cpu一样,执行一会方法A,不一定非要等方法A执行完
再去执行方法B,而是切换执行(谁抢到资源谁先执行);
run只是方法的调用
线程的状态

创建,就绪,阻塞,运行,销毁
在这里插入图片描述
线程就是内存中的一个对象,线程并不是调用start方法之后就立刻开始执行
而是表示准备好了(Cpu可能正在执行其他线程),应该进行排队。当Cpu有时间片了,就分配给这个线程开始执行,如果到时间了,那么停止运行,重新排队。重复这个过程,直至运行完毕。
如果运行中出现状况,那么会停止运行,进入阻塞状态,直至解除才能进入就绪状态,准备排队。如果没有解除那么就会中止。
简言之就是 创建(new Thread) 就绪(start()) 执行(run()) ( 阻塞 解除阻塞 ) 就绪 执行 反复循环直至执行完毕 挂起包括就绪和阻塞状态

你在哪里用到了多线程?
百度网盘多个任务同时下载
给数仓供数,处理工单案件
为什么要使用多线程?
处理大量数据,合理使用多线程提高程序效率
创建多少线程合适?

创建线程的方式

创建线程方法①: 继承Thread类

public class ExtendThreadDemo extends Thread {
    @Override
    public void run() {
        for (int i = 1; i <= 10; i++) {
            System.out.println(Thread.currentThread()+"坚持学习第  " + i + "  天");
        }
    }


    public static void main(String[] args) {
        new ExtendThreadDemo().start();
    }

}

运行效果
在这里插入图片描述

创建线程方式②:实现Runnable接口

public class Demo2 implements Runnable {
    @Override
    public void run() {
        for (int i = 1; i <= 10; i++) {
            System.out.println(Thread.currentThread()+"坚持学习第  " + i + "  天");
        }
    }

    public static void main(String[] args) {
       new Thread(new Demo2()).start();
    }

}

在这里插入图片描述
创建线程方式3:匿名内部类创建线程

public class Demo3 {
    public static void main(String[] args) {
        new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        for (int i = 1; i <= 10; i++) {
                            System.out.println(Thread.currentThread()+"坚持学习第  " + i + "  天");
                        }
                    }
                }

        ).start();
    }

}

运行效果
在这里插入图片描述

多线程线程安全

为什么会出现线程安全问题?
当多个线程同时共享同一个全局/静态变量,做写操作会出现数据冲突,
也就是线程安全问题;读不会;
public class Demo4 implements Runnable {
    int cocaCount = 1;

    @Override
    public void run() {
        while (cocaCount > 0) {
            shopping();
        }
    }


    public void shopping() {
        if (cocaCount < 100) {
            System.out.println("出售第 " + cocaCount + " 瓶可口可乐");
            cocaCount++;
        }
    }

    public static void main(String[] args) {
        Demo4 demo4 = new Demo4();
        new Thread(demo4).start();
        new Thread(demo4).start();
        new Thread(demo4).start();
        new Thread(demo4).start();
    }

}

这是四个线程,如果n个线程执行时调用了同一个对象的同一个方法,那么该方法资源被n个线程共享,n个线程轮转执行该方法。
一个线程修改了该方法的变量的值,下一个线程再调用这个方法会接着第一个线程的调用结果继续调用。
在这里插入图片描述
多线程会有并发(同时抢到了一个媳妇[资源],大家都认为是自己的媳妇,这就不安全了,各自洞房了各自的媳妇,孩子不知道是谁的了);
例如:线程A和线程B同时修改了数据库的同一个参数,数据库参数值结果不清楚是A修改的还是B修改的

解决方式① 加sysnchronized锁
synchronized修饰方法(用的是this锁),叫同步方法
synchronized修饰代码块,叫同步代码块

在这里插入图片描述
同步代码块加锁
加同步代码块输出

在这里插入图片描述
isAlive活着的定义是就绪、执行、阻塞状态
死了的定义是还没开始、执行完毕

线程是有优先级的,优先级高的获得Cpu执行时间长,并不代表优先级低的就得不到执行

并发变成内存模型

…后期补充

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值