Java--线程(一)(创建线程的方式及线程常用的几个方法)

一、什么是线程

  线程,又称轻量级进程。

  程序中的一个顺序控制流程,同时也是cpu的基本调度单位。

  进程由多个线程组成,彼此间完成完成不同的工作,交替执行,称为多线程。

  例如:迅雷是一个进程,当中的多个下载任务即是多个线程

二、线程和进程的区别

  进程是操作系统资源分配的基本单位,线程是cpu的基本调度单位。

  一个程序运行后至少有一个进程。

  一个进程可以包含多个线程,但是至少需要一个线程

  进程间不能共享数据段地址,但同进程的线程之间可以

三、线程的组成及特点

  任何一个线程都具有基本的组成部分:

    1.cpu时间片:操作系统会为每个线程分配执行时间。

    2.运行数据:

      堆空间:存储线程需要使用的对象,多个线程可以共享堆中的对象

      栈空间:存储线程需使用的局部编码,每个线程都拥有独立的栈

    3.线程的逻辑代码

  线程的特点:

    1.线程抢占式执行:效率高;可以防止单一线程长时间独占cpu

    2.在单核cpu中,宏观上同时执行,微观上顺序执行

四、创建线程的方式

  1、继承Thread类 重写run()方法

    获取线程名称:第一种方法:用this.getid() 和  this.getName() 获取线程的ID和名称

          第二种方法:用this.currentThread() 获取当前线程

      线程.setName();给线程名称赋值

      注意:线程的启动 用 start() 方法

      线程的名称可以修改 线程的ID不可修改

           

package com.monv.Thread;
/**
 * 创建线程类 继承 Thread
 * @author Administrator
 *
 */
public class MyThread extends Thread{
    
    public MyThread() {
        // TODO Auto-generated constructor stub
    }
    
    public MyThread(String name){
        super(name);
    }
    
    @Override
    public void run() {
        for(int i = 0;i<100;i++){
            //1.第一种方法 用this.getid() 和  this.getName() 获取线程的ID和名称
//            System.out.println("线程ID:"+this.getId()+"线程名称:"+this.getName()+"子线程执行-------"+i);
            //2.第二种方法 用this.currentThread() 获取当前线程
            System.out.println("线程ID:"+this.currentThread().getId()+" 线程名称:"+this.currentThread().getName()+" 子线程执行------"+i);
        }
    }
}
---------------------------------------------------------
package com.monv.Thread;
/**
 * 测试线程 main是主线程
 * @author Administrator
 *
 */
public class TestThread {
    public static void main(String[] args) {
        //1.创建线程
        MyThread testMyThread = new MyThread("这是第一个子线程");
        //2.启动线程,用Start,不能用Run
        //修改线程的名称 要写在线程执行前
//        testMyThread.setName("这是第一个子线程");
        testMyThread.start();
        
        MyThread testMyThread2 = new MyThread("这是第二个子线程");
        //2.启动线程,用Start,不能用Run
        //修改线程的名称 要写在线程执行前
//        testMyThread2.setName("这是第二个子线程");
        testMyThread2.start();
        //主线程执行
        for (int i = 0; i <100; i++) {
            System.out.println("主线程执行=============="+i);
        }
    }
}

 

 2.实现Runnable接口 重写run()方法

  注意:Runable也可以用内部类的方法实现

package com.monv.Thread;

public class MyRunnable implements Runnable{

     @Override
    public void run() {
        for (int i = 0; i<100 ;i++){
            System.out.println(Thread.currentThread().getName()+"++++++++++"+i);
        }
    }
}
------------------------------------------------------
package com.monv.Thread;

public class TestRunnable {
    public static void main(String[] args) {
        //1.创建MyRunnable对象,表示线程要执行的功能
        MyRunnable runnable = new MyRunnable();
        //2.创建线程
        Thread thread = new Thread(runnable, "我的线程");
        //3.执行
        thread.start();
        
        for (int i = 0; i < 100;i++){
            System.out.println("main------------"+i);
        }
    }
}
-------------------------------------------------
-------------匿名内部类方法实现---------------------
package com.monv.Thread;

public class TestRunnable {
    public static void main(String[] args) {        
        //创建匿名内部类
        Runnable runnable = new Runnable() {
            
            @Override
            public void run() {
                for (int i = 0; i < 100;i++){
                    System.out.println(Thread.currentThread().getName()+"++++++++++++"+i);
                }                    
            }
        };
        
        Thread thread = new Thread(runnable, "我的线程");
        thread.start();
        
        for (int i = 0; i < 100;i++){
        System.out.println("main------------"+i);
        }
    }
}

 

五、线程的状态

 

 

六、常见的方法

  1.休眠:public static void sleep(long millis); 当前线程主动休眠millis毫秒

  2.放弃:public static void yield(); 当前主线程主动放弃时间片,回到就绪状态,竞争下一次时间片

  3.加入:public final void join();允许其他线程加入到当前线程中

--------1.sleep-----------
package com.monv.Thread;

public class SleepThread extends Thread{
    @Override
    public void run() {
        for (int i =0 ;i<10 ;i++){
            System.out.println(Thread.currentThread().getName()+"............."+i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}
---------测试-------------
package com.monv.Thread; public class TestSleep { public static void main(String[] args) { SleepThread s1 = new SleepThread(); s1.start(); SleepThread s2 = new SleepThread(); s2.start(); } } --------2.yield----------- package com.monv.Thread; public class YieldThread extends Thread{ @Override public void run() { for(int i =0;i< 10;i++){ System.out.println(Thread.currentThread().getName()+"+++++++++++"+i); //主动放弃cpu Thread.yield(); } } }
---------测试------------------
package com.monv.Thread; public class TestYield { public static void main(String[] args) { YieldThread y1 = new YieldThread(); YieldThread y2 = new YieldThread(); y1.start(); y2.start(); } } --------3.join----------- package com.monv.Thread; public class JoinThread extends Thread{ @Override public void run() { for (int i = 0; i < 30; i++) { System.out.println(Thread.currentThread().getName()+"........."+i); try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
----------测试---------------
package com.monv.Thread; public class TestJoin { public static void main(String[] args) { JoinThread jo1 = new JoinThread(); jo1.start(); try { jo1.join();//把j1加入当前线程(主线程main),并阻塞当前线程,直到加入线程执行完毕当前线程才会继续执行 } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } //主线程 for (int i =0;i<20;i++){ System.out.println(Thread.currentThread().getName()+"......"+i); try { Thread.sleep(300); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }

 七、线程等待

 

posted @ 2021-01-18 15:38  改Bug的小魔女  阅读(160)  评论(0编辑  收藏  举报