JAVA基础--Thread多线程简单应用(1)

本文介绍了Java中多线程的基本概念及其实现方法,包括进程与线程的区别、多线程的优势、创建线程的不同方式及其特点,并通过具体示例展示了如何在Java中创建和使用多线程。

      系统中,为了更换的利用CPU资源,提高运行效率,就一定会用到多线程;那么JAVA中的多线程又是什么样的? 接下来就一一测试JAVA中线程的使用方法:

 1, 线程的基本用法:

package thread;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 *@description 
 *
 *  JAVA 线程的用法测试
 *
 *@date  2018/1/3
 *@author  geYang
 **/
public class MyThread {
    
    /**
     * 知识点:
     * 
     * A:什么是进程,什么是线程?
     * 1, 进程 : 进程是正在运行的程序,是线程的集合,每一个应用程序中都会有一个进程, 是执行某个程序, 一个操作系统中会有多个进程;
     * 2, 线程 : 线程是CPU的最小执行单元,一条执行路径,一个执行流程,在任何一个进程中都会有一个线程,称为该进程的主线程;
     *      如 main方法就是该程序的主线程; 每个线程间是独立,互不影响,交替进行的;
     * 
     * 为什么使用多线程:
     *  使用多线程,更好的利用CPU的资源,提高程序运行效率,提高用户体验;  多线程并不是提高宽带速度,而只是提高程序效率;
     * 
     * B:创建线程有那些方式:
     *  1: 使用继承  Thread 类,重写 run() 的方式; 
     *  2: 使用实现Runnable接口方式;
     *  3: 使用匿名内部类方式;
     *  4: 使用Calable和Future创建具备返回值的线程;
     *  5: 使用线程池创建线程;
     * 
     * C:创建线程的那种方法好?
     *   实现接口的方法,面向接口编程;
     *
     * D:同步 和 异步:
     *  1: 同步: 代码从上往下顺序的执行;单线程; 
     *  2: 异步: 多线程; 多个执行路径,互不影响; CPU执行权,每次CPU调度不相同;
     * 
     * E:什么是守护线程,什么是非守护线程:
     *  1: 守护线程: 守护线程和主线程一起销毁; 如我们的gc线程(垃圾回收),它有一个特征:主线程挂掉,守护线程也会挂掉;
     *  2: 非守护线程: 和主线程互不影响; 如用户线程,用户创建的线程,当主线程挂掉之后,用户线程还会继续执行;
     * 
     * F:并行与并发:
     *  1: 并行:多个CPU实例或者多台机器同时执行一段处理逻辑,是真正的同时;
     *  2: 并发:通过CPU调度算法,让用户看上去同时执行,实际上从CPU操作层面不是真正的同时;
     * 
     * G:线程的几种状态:
     *  新建(new Thred())------->准备状态(start())----------->运行状态(run())----->死亡(stop())
     *                            ^                             /
     *                             \---休眠状态(sleep(),wait())<---
     * */
    
    /**
     * main 方法 为当前项目的主线程
     * @throws Exception 
     * */
    public static void main(String[] args) throws Exception {
      /*  JAVA开启线程的几种方法  */
        //1: 调用继承Thread的线程创建方法:
        new ThreadOne().start();
        
        //2: 使用实现Runnable接口方式;
        new Thread(new ThreadTwo()).start();
        
        //3: 使用匿名内部类创建
        new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=0;i<10;i++){
                    System.out.println("run3::"+i);
                }
            }
        }).start();
        
        new Thread(()->System.out.println("run3.1::In Java8")).start();
        
        //4: 使用Calable和Future创建具备返回值的线程:
        ThreadFour t4 = new ThreadFour();
            // 使用FutureTask来包装Callable对象
        FutureTask<Object> task = new FutureTask<Object>(t4);
        new Thread(task).start();
        try {
            System.out.println("run后返回值"+task.get());
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        
        /**
         * 5: 使用线程池创建线程
         * java.uitl.concurrent.ThreadPoolExecutor
         * 类是线程池中最核心的一个类,因此如果要透彻地了解Java中的线程池,必须先了解这个类;
         * 线程池部分内容较多,一会在新的文件中测试;
         * 
         * */
        
        // 主线程循环
        for(int i=0;i<5;i++){
            System.out.println("main::"+i);
        }
        
        /**
         * 线程常用API: 
         * */
        /* 获取线程的ID和名称 */
        Thread threadMain = Thread.currentThread();
        long id = threadMain.getId();
        String name = threadMain.getName();
        System.out.println("主线程ID="+id+"主线程名="+name); 
        
        ThreadOne threadOne = new ThreadOne();
        System.out.println("threadOne-ID="+threadOne.getId()+"子线程名="+threadOne.getName());
        Thread threadTwo = new Thread(new ThreadTwo(),"xx");
        System.out.println("threadTwo-ID="+threadTwo.getId()+"子线程名="+threadTwo.getName());
        
        /* 设置线程名称 */
        threadTwo.setName("ThreadTwo");
        System.out.println("threadTwo-ID="+threadTwo.getId()+"子线程名="+threadTwo.getName());
        
        /* 休眠 */
//        主线程休眠;
        Thread.sleep(1000);
        
        /* 设置线程为守护线程 */
        threadTwo.setDaemon(true);
        threadTwo.start();
        
        /* 优先级 */
        threadTwo.join();
        
        for(int i=0; i<5 ; i++){
            System.out.println("Hello world");
        }
        
        
    }
    

}

/**
 * 1: 继承Thread重写run方法创建
 * */
class ThreadOne extends Thread{
    @Override
    public void run() {
        System.out.println("run1_ID="+getId()+"name="+getName());
        for(int i=0;i<5;i++){
            try {
                //设置线程休眠时间:单位毫秒
                sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("ID:"+getId()+"run1::"+i);
            //立马停止线程,不安全,不建议使用
            //stop();
        }
    }
}


/**
 * 2: 实现Runnable接口创建线程
 **/
class ThreadTwo implements Runnable{
    public ThreadTwo(){}
    public ThreadTwo(Thread thread){
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void run() {
        for(int i=0;i<5;i++){
            
            System.out.println(Thread.currentThread().getName()+"--run2::"+i);
        }
    }
}


/**
 * 3: 实现Callable接口来实现线程
 * */
class ThreadFour implements Callable<Object>{
    @Override
    public Object call() throws Exception {
        for(int i=0;i<5;i++){
            System.out.println("run4::"+i);
        }
        return 5;
    }
}

    2: 测试线程优先级:

package thread;

/**
 * 测试t1,t2,t3 顺序执行(优先级)
 *
 * join() 
 *
 *
 **/
public class MyTherdTest1 {

    public static void main(String[] args) {
       
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=0;i<5;i++){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("t1:::"+i);
                }
            }
        }, "t1");
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    t1.join();
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                for(int i=0;i<5;i++){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("t2:::"+i);
                }
            }
        }, "t2");
        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    t2.join();
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                for(int i=0;i<5;i++){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("t3:::"+i);
                }
            }
        }, "t3");
        Thread t4 = new Thread(new Thread4(t3),"t4");
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        
    }
    
    
}

class Thread4 implements Runnable{
    private Thread thread;
    public Thread4(){}
    public Thread4(Thread thread){
        this.thread = thread;
    }
    @Override
    public void run() {
        if(this.thread!=null){
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        for(int i=0;i<5;i++){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+":::"+i);
        }
    }
}

3: 简单分配处理事件 测试:

package thread;

import java.util.ArrayList;
import java.util.List;

/**
 * 多线程 分批处理 事件 测试;
 * 
 * 分批发送短信举例;
 * 
 * */
public class MyTherdTest2 {
    public static void main(String[] args) {
        //1, 初始化用户数据;
        List<User> listUser = listUser(10);
        
        //2, 定义每批大小;
        int size = 2;
        
        //3, 分隔数据;
        List<List<User>> page = new PageUtil<User>(size, listUser).page();
        //4, 发送
        for(List<User> list : page){
            new Thread(new Send<User>(list)).start();
        }
        
    }
    
    private static List<User> listUser(int size){
        List<User> list = new ArrayList<>();
        for(int i=0;i<size;i++){
            list.add(new User(i,i+""+i));
        }
        return list;
    }
    
    
    
}
/**
 * 发送工具
 * */
class Send<T> implements Runnable{
    private List<T> list;
    public Send(List<T> list) {
        this.list = list;
    }
    @Override
    public void run() {
        for(T t : list){
            System.out.println(Thread.currentThread().getName()+";::"+t);
        }
    }
}

/**
 * 分页工具
 * */
class PageUtil<T>{
    private int size;
    private List<T> list;
    public PageUtil(int size, List<T> list) {
        this.size = size;
        this.list = list;
    }
    public List<List<T>> page(){
        int pages = (list.size()+size-1)/size;
//        System.out.println("页数:"+pages);
//        System.out.println("大小:"+size);
        
        List<List<T>> listL = new ArrayList<>();
        for(int i=0; i < pages; i++){
            int start = i*size;
            List<T> listT = new ArrayList<>();
            for(int j=start; j<start+size && j<list.size(); j++){
//                System.out.println(list.get(j));
                listT.add(list.get(j));
            }
//            System.out.println(listT);
//            System.out.println("==========");
            listL.add(listT);
        }
        return listL;
    }
    
    
    
}

/**
 * 用户对象
 * */
class User {
    private int id;
    private String phone;
    
    public User() {
    }
    
    public User(int id, String phone) {
        this.id = id;
        this.phone = phone;
    }

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", phone=" + phone + "]";
    }
}

好了,线程的简单使用就这样了,下次再来看看关于线程更高级的用法; 欢迎讨论交流;

转载于:https://my.oschina.net/u/3681868/blog/1601618

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值