博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java基础-多线程初步了解
阅读量:6926 次
发布时间:2019-06-27

本文共 3078 字,大约阅读时间需要 10 分钟。

把java基础撸一边,从简单的开始

学习多线程,首先要了解多线程。有很多概念还是要了解一下

对“程”的基本认识

(如果这个看了,下面的几段文字可以过,抄的)

有两种程,进程和线程

进程,是并发执行的进程在执行过程中分配和管理资源的基本单位,是一个动态概念,竞争计算机系统资源的基本单位。

线程,线程是进程的一部分,一个没有线程的进程可以被看作是单线程。线程有时又被成为轻量级进程,也是CPU调度的一个基本单位

线程的改变只代表CPU的执行过程的改变,而没有发生进程所拥有的资源变化。除了CPU之外,计算机的软硬件资源分配与线程无关,线程只能共享它所属进程的资源。

与进程控制表和PCB相似,每个线程也有自己的线程控制表TCB,而这个TCB中所保存的线程状态则比PCB表少得多,这些信息主要是相关指针用堆栈(系统栈和用户栈),寄存器中的状态数据。

进程拥有一个完整的虚拟机地址空间,不依赖于线程而独立存在;反之,线程是进程的一部分,没有自己的地址空间,与进程内的其他线程一起共享给该进程的所有资源。

java线程生命周期图(这图是我照着画的):

如果有兴趣的话,也可以画画。

以下是我乱逼逼,自己的认识。最好看官方的

线程的生命状态:新建状态,就绪状态,运行状态,阻塞状态,死亡状态

阻塞状态的时候,有两个定义,等待,和堵塞。等待:(理解)线程要进入的CPU被其他线程占用,服务执行该线程的任务。阻塞状态,代码notify()方法,或者说,除系统通知外叫醒这个线程的是等待。而堵塞是系统叫醒,比如sleep()。睡眠玩时间之后,系统会通知这个线程结束了。

Thread对象实例化后执行start()方法并没有马上去执行run()方法,而是在在Runnable就绪状态去抢夺CPU资源开始运行。起跑100米也要准备以下start()后就是需要准的强制CPU资源的那一瞬间,到了Running运行状态后如果执行完毕或者有异常退出,这个线程也就执行完毕Dead死亡了。

但还有可能在运行过程中出现堵塞状况,比如sleep()睡眠,join()方法就会出现堵塞,当sleep结束或者join终端,I/O完成的时候会重新到Runnable准备去抢占CPU资源,而正在执行的Running的线程在yield的时候就与礼让CPU资源 进入Runnable状态

在Running状态的时候synchronize会进入锁,这个时候会等待处理一下。当同步锁被释放的时候会进入Runnable再去抢占资源

在Running状态的时候synchronize状态后wait()释放锁等待再到notify()唤醒锁,再次走当上面刚刚说的堵塞中。这里就基本了解了线程的运行状态

这是上面我推荐的博客上面的

简单看一下源码

下面是基本的使用,线程有两个中重要的类,一个是抽象类,Runnable,一个是Runnable实现类Thread。使用线程的时候一般是new Thread().start();这样就可以开启一个线程

还有就是实现Runnable的类,比如A实现了Runnable类,

A a = new A;

new Thread(a).start();这样也可以开启一个线程。两者的实现不同来自于对Thread类不同的构造方法不同

public Thread() {    init(null, null, "Thread-" + nextThreadNum(), 0);}public Thread(Runnable target) {    init(null, target, "Thread-" + nextThreadNum(), 0);}复制代码

在来看看Runnable类

public interface Runnable {      public abstract void run();}复制代码

run()方法里面就是这个线程的执行内容。

再来看看Thread的start()方法

public synchronized void start() {      if (threadStatus != 0)        throw new IllegalThreadStateException();    group.add(this);    boolean started = false;    try {        start0();        started = true;    } finally {        try {            if (!started) {                group.threadStartFailed(this);            }        } catch (Throwable ignore) {        }    }}private native void start0();复制代码

看到native就知道是去调用C代码

start0()方法会新运行一个线程,新线程会调用run()方法。

public void run() {    if (target != null) {        target.run();    }}复制代码

这样一来就可以理清楚继承Thread类和实现Runnable类两种基本用法的区别

通过继承Thread类的需要去实现Thread。因为在构建方法中init方法是传递的null去赋值的。如果是创建传递了Runnable中,是传递过去。并且赋值,这样再run()方法中判断了target()并且运行了该实现Runnable类的run()方法

基本实现

知道这个代码背景,就对线程的使用有了一个概念。

public class Demo1 extends Thread{    public Demo1(String name){        super(name);    }    @Override    public void run() {        while (!interrupted()) {            System.out.println("线程 :"+getName());        }    }    public static void main(String[] age){        Demo1 a = new Demo1("A");        a.start();    }}复制代码

继承Thread的实现

public class Demo2 implements Runnable {    public static void main(String[] age){        Demo2 demo2 = new Demo2();        Thread thread = new Thread(demo2);        thread.start();    }    public void run(){        while (true){            System.out.println("thread running ...");        }    }}复制代码

实现抽象类的Runnable

转载于:https://juejin.im/post/5c7ddd9e6fb9a049b07e17e3

你可能感兴趣的文章
提示输入 用户名 ,密码,--》转
查看>>
Ubuntu Broadcom无线网卡驱动安装
查看>>
T[]与List<T>的使用时机
查看>>
wap 媒体查询对应iphone手机的大小范围
查看>>
在Windows Server 2008上配置Memcached
查看>>
LINQ to SQL with NOLOCK
查看>>
Sencha-命令-CMD(Ant集成)(官网文档翻译34)
查看>>
vim快捷键
查看>>
【HDOJ】5155 Harry And Magic Box
查看>>
第4次冲刺练习
查看>>
并发编程之 Fork-Join 分而治之框架
查看>>
Spring @Import注解 —— 导入资源
查看>>
jquery 事件委托(利用冒泡)
查看>>
javascript数组去重算法-----4(另一种写法)
查看>>
mongodb启动关闭;
查看>>
MYSQL错误:You can't specify target table for update in FROM clause
查看>>
Java-输入输出流
查看>>
趣题C解(1)--李白喝酒问题
查看>>
【HTML5&CSS3进阶学习01】气泡组件的实现
查看>>
CKEditor网页编辑器实例中文解析
查看>>