zoukankan      html  css  js  c++  java
  • java的多线程(一)

         我们知道我们打开个程序(或者说运行一款软件)其实也就是创建了一个进程,只不过程序是静态指令的集合,而进程是正在系统中运行的指令集合,进程是系统进行资源分配与调度的一个独立单位。进程具有独立性,动态性,并发性。现在的操作系统都支持并发,但在具体实现的细节上,根据硬件和操作系统的不同存在不同的策略,比较常用的方式有:共用式的多任务操作策略,抢占式的多任务策略。

        线程扩展了进程的概念,线程是进程的执行单元,线程在进程中也是独立存在的,是一种并发的执行流,当进程被初始化之后,主线程就被创建出来了。对于绝大多数程序来说只有一个主线程,我们可以同时创建多条线程顺序执行流也就是线程。也就是说线程是进程的组成部分,一个进程可以拥有多个线程,一个线程必须有一个父进程。线程可以拥有自己的堆栈,自己的计数器,自己的局部变量等。但他们不在拥有系统资源,而是与其他线程之间共享该进程所拥有的所有的资源。线程用来完成一定的任务,可与其他线程之间共享父进程中的共享变量及部分环境,相互之间协同来完成进程所要完成的工作。

        简单来说:一个程序运行后至少有一个进程,一个进程里可以包含多个线程,但至少包含一个线程。

    线程的创建和启动:

    Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例,每条线程的任务就是完成一定的任务,实际就是执行一段程序流,而java使用run方法来封装这段程序流。接下来介绍两种创建线程的方法。

    第一种继承Thread类来创建线程类:

    1、定义Thread类的子类,并重写Thread类的run方法,这个run方法的方法体就代表了线程需要完成的任务,就是线程执行体了。

    2、创建Thread类子类的实例,也就是创建线程对象。

    3、用线程的start方法来启动线程。

    下面是一个具体的例子:

    /**
     * 
     */
    package cn.wan;
    /**
     * @author Administrator
     *
     */
    public class TestHread extends Thread{
    
        private int i;
        
        public void run()
        {
            for(;i<20;i++)
            {
                System.out.println(getName()+""+i);
            }
        }
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
    
            for(int i = 0;i<100;i++)
            {
                System.out.println(Thread.currentThread().getName()+""+i);
                if(i== 20)
                {
                    new TestHread().start();
                    System.out.println("AAAAAAAAAAAAAAAAAAAAAAAAAA");
                    new TestHread().start();
                }
            }
        }
    
    }

    当Java程序运行时,至少会创建一个线程,那就是主线程,主线程的线程执行体不是由run方法来确定的,而是由main方法来确定的。main方法的方法体代表主线程的线程执行体。

    第二种实现Runnable接口创建线程类

    1、定义Runnable接口的实现类并重写该接口的run方法,该run方法的方法体同样是该线程的线程执行体。

    2、创建Runnable实现类的实例,并以此实例来作为Thread类的target来创建Thread对象。这个Thread类的实例才是真正的线程对象。

    //   创建Runnable接口实现的对象,SecondThread类实现了这个接口,
       SecondThread st = new   SecondThread();
       Thread th = new Thread(st);

    下面是一个具体有的例子:

    package cn.wan;
    
    public class SecondThread implements Runnable{
    
    
        private int i;
        @Override
        /**
         * run方法同样是线程的执行体
         */
        public void run() {
            // TODO Auto-generated method stub
            for(;i<100;i++)
            {
                // 当线程类实现Runnable接口时
                // 如果想获得当前线程,只能用Tread.currentThread()方法
                System.out.println(Thread.currentThread().getName()+""+i);
            }
            
        }
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
    
            for(int i = 0;i<100;i++)
            {
                System.out.println(Thread.currentThread().getName()+""+i);
                if(i== 20)
                {
                    SecondThread st = new SecondThread();
                    //  通过new Thread(target,name)方法创建新线程
                    new Thread(st,"first one").start();
                    System.out.println("AAAAAAAAAAAAAAAAAAAAAAAAAA");
                    new Thread(st,"second one").start();
                }
            }
        }
    }

    第一种和第二种方法主要差别在:

    第一种

    劣势:因为线程类已经继承了Thread类,所以不能再继续继承父类。

    优势:编写简单,如果需要访问当前进程只需使用this关键字即可。无需使用Thread.currentThread方法。

    第二种

    劣势:编写复杂,如果需要访问当前线程需要使用Thread.currentThread方法。

    优势:线程类只是继承了Runnable接口,还可以继承其他类。同时多线程可以同时共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况。

  • 相关阅读:
    手撕 Goroutine 同步问题
    go基础知识面试备忘录
    专题3:链表类题型总结(go)
    python自动化开发-[第四天]-函数
    NOIP 飞扬的小鸟 题解
    集合 Properties 的 简单例子(Spring)
    Linux常用命令
    网络安全系列索引
    关于个人博客
    使用User Agent和代理IP隐藏身份
  • 原文地址:https://www.cnblogs.com/duhuo/p/4374654.html
Copyright © 2011-2022 走看看