java实现多线程的四种方式

1.通过继承Thread来创建线程

  • 由于java单继承的机制,所以这种创建线程的方式不太推荐,当某一个类有一个直接父类,那么他就不能当线程类来使用了.
  • 调用start方法相当于是创建分支栈,这个栈的run方法跟主线程的main方法是平级的,开好栈以后,由jvm自动调用.
public class Thread2 {
    public static void main(String[] args) {
        new Test2().start();

        for (int i = 0; i < 1000; i++) {
            System.out.println("主线程------->"+i);
        }
    }
}

class Test2 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println("分支线程------>");
        }
    }
}

2.通过(三种写法)来实现runnable接口来创建线程

第一种方式(创建一个实现Runnable接口的类,在把该类的实现类对象作为Thread的构造器参数来创建线程,写法比较繁琐):

public class Thread1 {
    public static void main(String[] args) {

        new Thread(new Test()).start();
        for (int i = 0; i < 1000; i++) {
            System.out.println("主线程------>"+i);
        }

    }
}

class Test implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println("分支线程----->"+i);
        }
    }
}

第二种方式(通过匿名内部类的方式来创建Runnable的实现类对象,写法得到简洁):

public class Thread1 {
    public static void main(String[] args) {

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    System.out.println("子线程------>"+i);
                }
            }
        }).start();

        for (int i = 0; i < 1000; i++) {
            System.out.println("主线程------>"+i);
        }

    }
}

第三种方式(通过lambda表达式进一步简化第二种方式):

public class Thread1 {
    public static void main(String[] args) {

        new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                System.out.println("分支线程----->"+i);
            }
        }).start();
        for (int i = 0; i < 1000; i++) {
            System.out.println("主线程------>"+i);
        }

    }
}

3.通过实现callable接口的方式来创建线程

优点:

  • 这中创建线程的方式相比上面两种方法可以获取线程的返回值
  • 这种线程还可以抛出异常!
  • 优点就是当要实现多个线程操作同一个资源对象的时候比较好实现
  • 还可以指定返回值的泛型

缺点:

  • 这种方式创建线程当要获取返回值的时候,会造成main(其他)线程阻塞的情况,
public class CallableTest {
    public static void main(String[] args) {
        FutureTask<Integer> futureTask = new FutureTask<>(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                System.out.println("分支线程开始了---->");
                int a = 100;
                int b = 200;
                Thread.sleep(1000*5);
                return a+b;
            }
        });
        Thread t = new Thread(futureTask);
        t.start();
        try {
            Integer integer = futureTask.get();
            System.out.println(integer);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        System.out.println("主线程执行了---->");
    }
}

4.通过线程池的方式创建线程

线程池的相关参数:
1、corePoolSize: 核心线程数量,线程池中会存在这么多个线程,当线程数量(包含空闲线程)少于corePoolSize的时候,会优先创建新线程,可以设置allowCoreThreadTimeOut=true来让核心线程池中线程也移除
2、maximumPoolSize: 线程池的最大容量,线程池中的线程数量不得超过这么多个,除非阻塞队列设置为无界的
3、keepAliveTime: 空闲线程存活时间,线程空闲超过这个时间的时候就会销毁
4、unit: keepAliveTime的时间单位,分钟、秒等
5、workQueue: 线程工作队列,阻塞队列,线程池从这个队列中取线程,可以设置的队列类型(容量为:capacity):
  ArrayBlockingQueue:有界阻塞队列,当线程数量n:corePoolSize <= n < maximumPoolSize 且 n >= 
  capacity :创建新线程处理任务 当:n >= maximumPoolSize 且 n >= capacity 拒绝线程
  LinkedBlockingQueue: 无界队列,maximumPoolSize不起作用,会一直创建线程 会造成OOM 
  (outofmemory)
  SynchronousQuene: 不缓存任务,直接调度执行,线程数超过 maximumPoolSize 则直接拒绝线程
  PriorityBlockingQueue: 带优先级的线程队列
6、setRejectedExecutionHandler: 拒绝策略,线程数量达到maximumPoolSize时的策略,默认提供了4种:
  AbortPolicy: 直接丢弃并抛出异常
  CallerRunsPolicy: 线程池没有关闭则直接调用线程的run方法
  DiscardPolicy: 直接丢弃任务
  DiscardOldestPolicy: 丢弃最早的任务,并尝试把当前任务加入队列
7、ThreadFactory: 创建线程时使用的工厂,可以对线程进行统一设置,如是否守护线程、线程名等

 通过线程池创建线程:

public class ThreadPool {
    public static void main(String[] args) {
        //创建带有10个线程的线程池
         ExecutorService service = Executors.newFixedThreadPool(10);
         //上面的ExecutorService是一个接口,ThreadPoolExecutor是实现类对象
        ThreadPoolExecutor poolExecutor = (ThreadPoolExecutor) service;
        //设置核心线程的数量
        poolExecutor.setCorePoolSize(5);
        //设置空闲线程的存活时间
        poolExecutor.setKeepAliveTime(1000*60*60,TimeUnit.SECONDS);
        //设置线程最大数量
        poolExecutor.setMaximumPoolSize(10);
        //设置拒绝策略
        poolExecutor.setRejectedExecutionHandler(new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                
            }
        });
        //设置线程工厂
        poolExecutor.setThreadFactory(new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                
            }
        });

        //execute主要适用于runnable方式创建的线程
        service.execute(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 101; i++) {
                    if (i % 2 == 0){
                        System.out.println(i);
                    }
                }
            }
        });
        //submit方法既可以适用于Runnable,也适用于Callable
        service.submit(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 101; i++) {
                    if (i % 2 == 0){
                        System.out.println(i);
                    }
                }
            }
        });
        //通过callable来实现
        Future<Integer> future = service.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int sum = 0;
                for (int i = 0; i < 101; i++) {
                    sum += i;
                }
                return sum;
            }
        });
        try {
            //得到线程的返回值
            Integer sum = future.get();
            System.out.println("1-100的偶数和为:"+sum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        
        //关闭线程池
        service.shutdown();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zph_coder

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值