Java多线程基础

一、什么是多线程

1.线程与进程

进程:正在运行的程序。确切的来说,当一个程序进入内存运行,即是一个或多个进程在运行,具有一定独立功能。

线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。

区别:一个程序运行后至少有一个进程,一个进程中可以包含多个线程。

2.多线程的好处

提高程序的运行效率,使CPU的使用率更高。但是多线程并不能提高运行速度。

二、多线程的两种实现方式

1.继承Thread类创建线程
#1.定义一个Thread类的子类
public class MyThread extends Thread{
    //重写run方法,实现代码逻辑
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(getName() + "线程!" + i);
        }
    }
}

#2.开启线程动作,查看线程的执行结果
public class Demo1 {
    public static void main(String[] args) {
        //创建线程对象
        MyThread thread1 = new MyThread();
        MyThread thread2 = new MyThread();
        //开启线程动作        
        thread1.start();
        thread2.start();

        //返回main主线程
        Thread mainTread = thread1.currentThread();

        for (int i = 0; i < 10; i++) {
            System.out.println(mainTread.getName()+ ":" + i);
        }
    }
}
2.实现Runnable接口创建线程
#1.定义线程执行目标子类
public class MyRunnable implements Runnable {
    //定义线程执行目标的逻辑
    @Override
    public void run() {
        //得到当前线程名字
        Thread thread = Thread.currentThread();

        for (int i = 0; i < 10; i++) {
            System.out.println(thread.getName()+ ":" + i);
        }   
    }
}

#2.开启线程动作,查看线程的执行结果
public class Demo2 {
    public static void main(String[] args) {
        //创建线程的执行目标对象
        Runnable runnable = new MyRunnable();
        //通过线程执行目标创建线程对象
        Thread thread1 = new Thread(runnable);
        thread1.setName("charliexm");
        Thread thread2 = new Thread(runnable);
        thread2.setName("charliexg");
        //开启线程
        thread1.start();
        thread2.start();

        Thread thread = thread1.currentThread();    
        for (int i = 0; i < 10; i++) {
            System.out.println(thread.getName() + i);
        }
    }
}
3.两种实现方式的对比

继承Thread类,线程对象和线程任务耦合在一起。一旦创建Thread类的子类对象,既是线程对象,有又有线程任务。

实现Runnable接口,将线程任务单独分离出来封装成对象,类型就是Runnable接口类型,更加的符合面向对象。线程分为两部分,一部分线程对象,一部分线程任务。对线程对象和线程任务进行解耦。

4.使用匿名内部类创建线程示例
#方式一
//使用匿名内部类创建线程的子类对象
Thread thread = new Thread() {          
    @Override
    public void run() {
        System.out.println("我的线程执行了");
    }
};
thread.start();

//使用匿名内部类创建线程的子类匿名对象
new Thread() {          
    @Override
    public void run() {
        System.out.println("我的线程执行了2");
    }
}.start();

#方式二:
//使用匿名内部类的方式,创建线程执行目标类对象
//创建线程执行目标类对象
Runnable runnable = new Runnable() {            
    @Override
    public void run() {
        System.out.println("我的线程执行目标,执行了");
    }
};
//通过目标创建线程对象
Thread thread2 = new Thread(runnable);
//开启线程
thread2.start();

#方式三        
//使用匿名内部类的方式,创建线程执行目标类匿名对象
Thread thread3 = new Thread(new Runnable() {            
    @Override
    public void run() {
        System.out.println("我的线程执行目标,执行了2");
    }
});
thread3.start();

//使用匿名内部类的方式,创建线程执行目标类匿名对象,并且创建的是线程的匿名对象
new Thread(new Runnable() {         
    @Override
    public void run() {
        System.out.println("我的线程执行目标,执行了3");
    }
}).start();

三、线程池

线程池,其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源。

线程池主要用来解决线程生命周期开销问题和资源不足问题。通过对多个任务重复使用线程,线程创建的开销就被分摊到了多个任务上了,而且由于在请求到达时线程已经存在,所以消除了线程创建所带来的延迟。这样,就可以立即为请求服务,使用应用程序响应更快。另外,通过适当的调整线程中的线程数目可以防止出现资源不足的情况

线程池的使用方法:
1.利用Runnable接口向线程池提交任务

#1.定义线程执行目标类
public class Ticket implements Runnable{
    //定义线程执行目标的逻辑
    @Override
    public void run() {
        // TODO Auto-generated method stub
    }
}
#2.向线程池提交任务
public class ThreadPoolDemo1 {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        //创建一个线程池
        ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(3);

        //创建执行的任务类
        Ticket ticket = new Ticket();

        //提交任务
        newFixedThreadPool.submit(ticket);
        newFixedThreadPool.submit(ticket);
    }
}

2.利用Callable接口向线程池提交任务

#1.定义线程执行目标
public class Ticket2 implements Callable<String>{

    @Override
    public String call() throws Exception {
        // TODO Auto-generated method stub
        return "我是callable提交方式返回值";
    }
}

#2.向线程池提交任务
public class ThreadPoolDemo2 {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        //创建一个线程池
        ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(3);

        //callable的方式提交任务
        Ticket2 ticket2 = new Ticket2();
        Future<String> submit = newFixedThreadPool.submit(ticket2);

        //从综合结果中得到返回值
        String string = submit.get();       
        System.out.println(string);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值