java基础-多线程

Posted 邬家栋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java基础-多线程相关的知识,希望对你有一定的参考价值。

java多线程

进程与线程

进程:指一个正在执行的应用程序。每个进程执行都有一个执行顺序,该顺序称为一个执行路径或一个控制单元(进程是资源分配的最小单位)。一个进程包含1~n个线程

线程:指进程中某个单一顺序的控制流。线程控制着进程的执行(线程是CPU调度的最小单位)

多进程:指操作系统能同时运行多个任务(程序)
多线程:指在同一程序中有多个顺序流在执行

实现java多线程

在java中要实现多线程,有两种方式,一种是继承Thread类,一种是实现Runable接口

方式一:继承Thread类并复写run方法

步骤:

  • 自定义类继承Thread类
  • 在自定义类中复写Thread类中的run()方法(目的:将自定义代码存储在run方法中,让线程运行)
  • 创建类对象
  • 调用线程start方法(方法有两作用:启动线程,调用run方法

例1:

//自定义Demo类继承Thread类
class Demo extends Thread{
    //复写run()方法
    public void run(){
        for(int i=1;i<20;i++){
            System.out.println("Demo run"+"--"+i);
        }
    }

}

public class ThreadDemo{
    public static void main(String[] args){
        //创建线程Demo的线程对象
        Demo d = new Demo();
        //启动线程并执行该线程的run()方法
        //若是d.run()仅仅是对象调用run方法,而线程创建了并未运行
        d.start();
        for(int i =1;i<10;i++){
            System.out.println("wujiadong"+"--"+i);
        }
    }

}

运行结果:

wujiadong--1
wujiadong--2
wujiadong--3
wujiadong--4
wujiadong--5
wujiadong--6
wujiadong--7
wujiadong--8
wujiadong--9
Demo run--1
Demo run--2
Demo run--3
Demo run--4
Demo run--5
Demo run--6
Demo run--7
Demo run--8
Demo run--9
Demo run--10
Demo run--11
Demo run--12
Demo run--13
Demo run--14
Demo run--15
Demo run--16
Demo run--17
Demo run--18
Demo run--19

方式二:实现Runnable接口

步骤:

  • 定义类实现Runnable接口
  • 覆盖Runnable接口中的run方法
  • 创建Runnable接口的子类对象
  • 创建Thread类对象,并把Runnable接口的子类对象作为构造参数传递
  • 调用Thread类start方法开启线程并调用Runnable接口子类的run方法

例1:

class MyRunnable implements Runnable{
    public void run(){
        for(int i = 0;i<50;i++){
            System.out.println(Thread.currentThread().getName()+"--"+i);
        }
    }

}

public class Example1{
    public static void main(String[] arags){
        MyRunnable mr = new MyRunnable();
/*
        //创建线程
        Thread t1 = new Thread(mr);
        Thread t2 = new Thread(mr);
        //设置线程名称(推荐这种命名方法)
        t1.setName("wujiadong");
        t2.setName("jiangrui");
*/
        //第二种线程命名方法
        Thread t1 = new Thread(mr,"wujiadong");
        Thread t2 = new Thread(mr,"jiangrui");
        t1.start();
        t2.start();
    }

}

 

Thread和Runnable的区别

  • 继承Thread:线程代码存放在Thread子类run方法中
  • 实现Runnable:线程代码存放在接口子类的run方法中

实现Runnable接口相对于继承Thread类的优点:

  • 可共享一个目标对象,实现多个线程处理同一个资源
  • 可避免java单线程的限制

 

线程的生命周期  

  • 新建状态(New): 创建线程对象就绪状态(Runnable):  线程对象创建后,其他线程调用该对象的start方法,该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。即有执行资格无执行权
  • 运行状态(Running):  就绪状态的线程获取了CPU,执行程序代码。即有执行资格,有执行权
  • 堵塞状态(Blocked):  因为某种原因放弃CPU使用权,暂时停止运行。知道线程进入就绪状态,才有机会转到运行状态。即无执行资格无执行权
  • 死亡状态(Terminated):线程执行完了或因异常退出了run()方法,该线程结束生命周期

 

线程调度

  • 线程优先级
  • 线程休眠
  • 线程让步
  • 线程插队

线程优先级

lass ThreadPriority extends Thread{
    public void run(){
        for(int i =0;i<50;i++){
            System.out.println(Thread.currentThread().getName()+"--"+i);
        }
    }
}


public class Example13{
    public static void main(String[] args){
        ThreadPriority tp1 = new ThreadPriority();
        ThreadPriority tp2 = new ThreadPriority();
        ThreadPriority tp3 = new ThreadPriority();
        tp1.setName("线程a");
        tp2.setName("线程b");
        tp3.setName("线程c");

        //System.out.println(tp1.getPriority());获取默认的优先级
        //设置优先级
        tp1.setPriority(10);
        tp2.setPriority(5);
        tp3.setPriority(1);

        tp1.start();
        tp2.start();
        tp3.start();
    }
}

 

线程休眠

import java.util.Date;
class MyThread extends Thread{
    public void run(){
        for(int i = 0;i<100;i++){
            System.out.println(Thread.currentThread().getName()+"---"+i+",日期"+new Date());
            try{
                Thread.sleep(1000);
            }catch(InterruptedException e){
                e.printStackTrace();
            }

        }
        
    }
}


public class Example14{
    public static void main(String[] args){
        MyThread mt1 = new MyThread();
        MyThread mt2 = new MyThread();
        MyThread mt3 = new MyThread();

        mt1.setName("邬家栋");
        mt2.setName("江睿");
        mt3.setName("徐晴玉");
        
        mt1.start();
        mt2.start();
        mt3.start();
    }
}

/*
上面代码需注意捕获异常或抛出异常

部分运行结果
邬家栋---0,日期Mon Oct 17 04:36:19 PDT 2016
江睿---0,日期Mon Oct 17 04:36:19 PDT 2016
徐晴玉---0,日期Mon Oct 17 04:36:19 PDT 2016
邬家栋---1,日期Mon Oct 17 04:36:20 PDT 2016
江睿---1,日期Mon Oct 17 04:36:20 PDT 2016
徐晴玉---1,日期Mon Oct 17 04:36:20 PDT 2016
江睿---2,日期Mon Oct 17 04:36:21 PDT 2016
徐晴玉---2,日期Mon Oct 17 04:36:21 PDT 2016
邬家栋---2,日期Mon Oct 17 04:36:21 PDT 2016

*/

 

线程让步

class MyThread extends Thread{
    public void run(){
        for(int i = 0;i<50;i++){
            System.out.println(Thread.currentThread().getName()+"--"+i);
            Thread.yield();//暂停当前线程,并执行其他线程
        }
        
    }
}

public class Example16{
    public static void main(String[] args){
        MyThread mt1 = new MyThread();
        MyThread mt2 = new MyThread();

        mt1.setName("wujiadong");
        mt2.setName("jiangrui");

        mt1.start();
        mt2.start();

    }
}

/*
部分结果
...
wujiadong--41
jiangrui--30
wujiadong--42
jiangrui--31
wujiadong--43
jiangrui--32
wujiadong--44
...

*/

 

线程插队

class MyThread extends Thread{
    public void run(){
        for(int i=0;i<50;i++){
            System.out.println(Thread.currentThread().getName()+"--"+i);
        }
    }

}

public class Example15{
    public static void main(String[] args){
        MyThread mt1 = new MyThread();
        MyThread mt2 = new MyThread();
        MyThread mt3 = new MyThread();

        mt1.setName("wujiadong");
        mt2.setName("jiangrui");
        mt3.setName("sunqiangkun");
        
        //加入join后等mt1线程运行完才开始运行mt2和mt3
        mt1.start();
        try{
            mt1.join();
        }catch(InterruptedException e){
            e.printStackTrace();
        }
        mt2.start();
        mt3.start();
    }
}

/*
部分运行结果
...
wujiadong--47
wujiadong--48
wujiadong--49
jiangrui--0
jiangrui--1
jiangrui--2
...
jiangrui--8
jiangrui--9
jiangrui--10
jiangrui--11
jiangrui--12
...

*/

 

守护线程

class MyThread extends Thread{
    public void run(){
        for(int i = 0;i<100;i++){
            System.out.println(Thread.currentThread().getName()+"---"+i);
        }
    }
}

public class Example17{
    public static void main(String[] args){
        MyThread mt1 = new MyThread();
        MyThread mt2 = new MyThread();
    
        mt1.setName("关羽");
        mt2.setName("张飞");
        //设置守护线程
        mt1.setDaemon(true);
        mt2.setDaemon(true);        

        mt1.start();
        mt2.start();

        Thread.currentThread().setName("刘备");//设置main线程名称
        for(int x = 0;x<6;x++){
            System.out.println(Thread.currentThread().getName()+x);//打印当前线程(main线程)名称
        }
    
    }
}

/*
设置了关羽张飞两个为守护线程
只要刘备这个线程结束了,则另外两个线程也要结束。


*/

 































以上是关于java基础-多线程的主要内容,如果未能解决你的问题,请参考以下文章

java基础入门-多线程同步浅析-以银行转账为样例

java多线程基础

Java基础之多线程

Java多线程基础

多线程编程学习一(Java多线程的基础)

Java 多线程基础多线程的实现方式