Java基础 | 多线程四种创建方式

程序、进程、线程

  • 程序:程序本身是静态的,我们开发程序,就是为了完成特定任务、用某种语言编写的一组指令的集合。
  • 进程:对进程来说,其就是程序装载入内存,开始运行的状态,是一个动态的概念。而且,进程是资源分配的基本单位,系统在运行的时候,会给进程分配不同的内存区域
  • 线程:对于进程来说,其可以划分为好几个线程。线程是操作系统调度和执行的单位,每个线程都有自己的独立运行栈和程序计数器,线程切换开销比较小。一个进程中的多个线程共享同一块内存单元、内存地址空间,也就是说从同一块堆中分配对象,可以访问相同的变量和对象。

线程的创建和使用

对Java来说,其线程的创建方式有数种,这里开始逐条介绍

1、继承Thread来重写run方法

Java中声明一个线程使用Thread类,这种创建方式需要自己继承Thread类,然后重写run方法来执行自己想要的逻辑,最后开启线程必须使用start方法

run方法只是此线程被调度时会执行的逻辑

以下为测试Demo,分别用两个线程打印奇数和偶数:

public class ThreadDemo
{
    public static void main(String[] args) {
        MyThread1 thread1=new MyThread1();
        MyThread2 thread2=new MyThread2();
        
        thread1.start();
        thread2.start();
    }
}


class MyThread1 extends Thread
{

    @Override
    public void run() {
        for(int i=0;i<100;i++)
        {
            if(i%2==0)
            {
                System.out.println("偶数: "+i);
            }
        }
    }
}

class MyThread2 extends Thread
{

    @Override
    public void run() {
        for(int i=0;i<100;i++)
        {
            if(i%2!=0)
            {
                System.out.println("奇数: "+i);
            }
        }
    }
}

这里如果开启线程时,start方法调用后会自己调用run方法。如果开始线程使用run方法,那么多线程效果失效。

3、实现Runable接口,重写run方法

class Window  implements Runnable{
    private int ticket=100;
    Object object=new Object();

    @Override
    public void run() {
        while(true)
        {
            synchronized(object)
            {
                if(ticket>0)
                {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+":卖票,票号为:"+ticket);
                    ticket--;
                }
                else
                {
                    break;
                }
            }

        }
    }
}

这种方式是比较建议使用的

3、实现Callable接口

不多絮叨,直接上代码

public class ThreadNew
{
    public static void main(String[] args) {
        //3.创建Callable接口实现类的对象
        NumThread numThread=new NumThread();
        //4.将Callable接口实现类的对象作为传递到FutureTask构造器中,创建FutureTask的对象
        FutureTask futureTask = new FutureTask(numThread);
        //5.将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start()方法
        new Thread(futureTask).start();
        try {
            //6.如果需要返回值可以使用FutureTask对象的get()方法拿到返回值
            Object obj = futureTask.get();
            System.out.println("和为:"+obj);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
//1.创建一个实现了Callable的类
class NumThread implements Callable
{

    //2.重写call()方法 其返回值是Object类型
    @Override
    public Object call() throws Exception
    {
        int ans=0;
        for (int i = 1; i <=100; i++)
        {
            if(i%2==0)
            {
                System.out.println(i);
                ans+=i;
            }
        }
        return ans;
    }
}

学到这里我就要批评一下Java的线程,拿个返回值需要这么多步,C++的原生POIX线程可以直接通过指针参数,拿到一个线程的返回值。

4、使用线程池

为了避免频繁地创建和销毁线程,提供资源利用率,我们可以用线程池技术来实现重复利用线程。

public class ThreadPoolTest
{
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        //executorService.execute(new NumThread1());  //适合Runnable接口
        executorService.submit(new NumThread2()); //适合Callable接口
    }
}

class NumThread1 implements Runnable
{
    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            if(i%2==0)
            {
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
}

class NumThread2 implements Callable
{
    @Override
    public Object call() throws Exception {


        for (int i = 1; i <= 100; i++) {
            if(i%2==0)
            {
                System.out.println(i);
            }
        }

        return null;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值