java线程浅析[初识线程]

java线程浅析[初识线程]

前言:

本来这段时间学习的是C/C++一类的知识,知识最近看到了C一块的线程,因为是标准库函数提供的,所以理解和使用的时候其实要比java的线程相对要稍微难一点,而线程这一段,其实算是代码中相对比较难的一部分,所以想着还是把java的线程和C语言下一类的线程做一个整体性的总结学习,在两者的相互对比中,看到共同点,差异点,当然因为本人也是一个new coder,所以可能有一些总结的不对的地方,希望各位看官能够及时的指出。

首先还是简单介绍一下什么是线程吧

对比一下程序,进程以及线程
程序:就是安装在磁盘上的一个指令集合,是一种静态的概念

进程:运行中的程序,当然一个程序可能fork出很多子进程,进程算是程序的子集,她是一种动态的概念,而每个进程其实都是有自己的独立的资源

线程:又被称为轻量级的进程,也就是程序执行的最小单元,是程序中一个单一顺序控制的流程。线程是进程中的一个实体,它是被系统独立调度和分配的基本单位,也就是进程的子集

那什么有是多线程呢?

多线程:就是单个程序中可以同事运行多个不同的线程,通过这些不同的线程来执行不同的任务

多线程具有的特点:
    1:一个进程同时包含一个或者多个线程
    2:如果一个程序需要实现多个代码同时交替运行,那么这个时候就是需要产生多个线程
    3:线程本身是不具有系统资源,而是与同属一个进程的其他线程共享了所在进程所拥有的资源
    4:同一个进程的多个线程能够并发执行,cpu会随机抽出时间让我们的程序选择执行不同的功能代码

多线程的目的:
    “最大的利用Cpu”就是多线程编程的主要目的
    也是就当某个线程不需要占用cpu资源的时候,让需要占用cpu资源的线程有机会获取cpu资源

关于线程的创建方式

1:直接使用Thread去创建或者使用自定义的Thread

当一个普通的类去继承Thread类的时候,就能通过start方法去启动线程,执行线程中的run方法
Thread的子类能够实例话。但是子类中需要去掉super方法。不然可能会执行递交的task任务

2:一个类去实现Runable,然后再通过Thread去执行这个task

通过runable接口的类必须借助Thread类才能创建线程,
创建一个Runable接口类实例
创建一个Thread的对象,将第一步的Runable对象作为参数传入Thread中
通过Thread的start方法去启动执行

直接上代码

package com.zzf.demo.thread;


/**
 * 注意Runable其实不是线程,它只是线程执行的一个task任务。所以真正的线程其实只有thread。
 * runable只是一个接口而已,而我们如果去翻看相关源码的时候,其实就可以看到,Thread的父亲其实就是Runable
 * @author dean
 *
 */
public class MyThreadImplementsRunable implements Runnable{

    @Override
    public void run() {
        // TODO Auto-generated method stub
        System.out.println("this is a MyCustomRunable implements Runable");
    }

}
package com.zzf.demo.thread;

public class MyThreadExtendsThread extends Thread{

    /**
     * 无参数的构造方法
     */
    public MyThreadExtendsThread() {
        super();
    }

    /**
     * @param target 任务
     * @param name 线程名字
     */
    public MyThreadExtendsThread(Runnable target, String name) {
        super(target, name);
        // TODO Auto-generated constructor stub
    }

    /**
     * @param target 执行的任务
     */
    public MyThreadExtendsThread(Runnable target) {
        super(target);
        // TODO Auto-generated constructor stub
    }

    /**
     * @param name 线程名字
     * 默认任务执行是会从线程本身的run方法中进行执行
     */
    public MyThreadExtendsThread(String name) {
        super(name);
        // TODO Auto-generated constructor stub
    }

    /**
     * @param group 将线程归属到某个线程组中去
     * @param target 执行的runable任务
     * @param name 线程名字
     * @param stackSize 栈的大小
     */
    public MyThreadExtendsThread(ThreadGroup group, Runnable target, String name, long stackSize) {
        super(group, target, name, stackSize);
        // TODO Auto-generated constructor stub
    }

    /**
     * @param group 线程组
     * @param target 目标task任务
     * @param name 线程名字
     */
    public MyThreadExtendsThread(ThreadGroup group, Runnable target, String name) {
        super(group, target, name);
        // TODO Auto-generated constructor stub
    }

    /**
     * @param group 线程组
     * @param target 目标task
     */
    public MyThreadExtendsThread(ThreadGroup group, Runnable target) {
        super(group, target);
        // TODO Auto-generated constructor stub
    }

    /**
     * @param group
     * @param name
     */
    public MyThreadExtendsThread(ThreadGroup group, String name) {
        super(group, name);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        //如果是super.run那么此时会调用runable中的方法,然后再去调自己的方法
        System.out.println("this is a thread extends from thread");
    }   
}
package com.zzf.demo.thread;

public class ThreadTestMain {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        MyThreadImplementsRunable customRunable = new MyThreadImplementsRunable();
        //向线程去递交一个执行任务,
        Thread thread  =new Thread(customRunable);
        thread.start();

        MyThreadExtendsThread thread2 = new MyThreadExtendsThread();
        //提交的是自定义的任务先执行自己本任务,然后线程再去执行自定义的任务,所以一般情况下都是由Thread递交task任务
        //一般不会去用自定义的线程来执行特殊的task任务,因为二者之间往往可能会产生一些冲突
        MyThreadExtendsThread thread3 = new MyThreadExtendsThread(customRunable);
        //在开发的过程中建议给你的线程起一个名字,因为如果一旦遇到问题,更方便我们去定位是哪一个线程出现了问题
        MyThreadExtendsThread thread4 = new MyThreadExtendsThread("myThread");

        thread2.start();
        thread3.start();
        thread4.start();
    }

}

当然这只是一个小小的Demo,主要就是讲怎么去创建线程,然而我们在实际的应用过程中,可能使用的时候为了图方便。调用方式五花八门。但是最终其实还是归根到原理性的一块
如:实际调用中可能出现的不规范,这种方式如果线程内部执行出错,可能定位稍微困难:

    new Thread(){
            public void run() {
                System.err.println("this is a thread");
            };
        }.start();
new Thread(new Runnable() { 
            @Override
            public void run() {
                // TODO Auto-generated method stub
                System.out.println("this is a runable thread");
            }
        }).start();

在线程的使用过程中,还有很多方法,如使用线程池去递交我们 task等。会在后续的博客中持续更新,结合javaApi以及源码的形式。

以上就是关于线程的一点简单介绍,切合的并不是太深入。有兴趣的可以去看看javaApi以及Thread的源码,其实总的来说java的线程调用等,其实是在native层去做的,翻过源码的可以看到,在Thread类中,有很多native方法。这些都是通过结合C中的线程来执行的。

欢迎持续访问博客,谢谢

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值