java 如何创建100个线程_Java 多线程一、创建线程的4中方式、线程常用方法

一、 创建线程的四种方式

方式一:继承自Thread 类

方法步骤

1.创建一个继承于Thread类的子类

2.重写Thread 类的 run()方法-> 将线程的执行操作声明到run()中

3.创建Thread 类的子类对象

4.通过此对象调用start() 方法

例如: 输出0~100 以内所有的偶数

public class ThreadInheritTest {

public static void main(String[] args) {

//3.new 一个继承自Thread类的对象

MyInheritThread myThread = new MyInheritThread();

//4.启动线程

myThread.start();

}

}

//1.创建一个继承自Thread 的子类

class MyInheritThread extends Thread {

//2.重写父类中Thread 的run方法

@Override

public void run() {

for (int i = 0; i < 100; i++) {

if (i % 2 == 0) {

System.out.println(Thread.currentThread().getName() + ": " + i);

}

}

}

}

注意:我们不能通过run方法启动线程,而是应该通过start方法启动线程。

方式二:实现Runnable 接口

方法步骤

1.创建一个实现Runnable接口的类。

2.重写Runnable 类的 run()方法-> 将线程的执行操作声明到run()中

3.创建实现当前Runnable 接口类的对象。

4.将上述对象作为参数传入到Thread 类的构造器中。

5.通过Thread类的对象调用start() 方法启动线程。

例如:输出1~100 以内所有的偶数

public class ThreadRunnableTest {

public static void main(String[] args) {

MyRunnableThread myRunnableThread = new MyRunnableThread();

Thread t1 = new Thread(myRunnableThread);

t1.start();

}

}

class MyRunnableThread implements Runnable {

@Override

public void run() {

for (int i = 0; i < 100; i++) {

if (i % 2 == 0) {

System.out.println(Thread.currentThread().getName() + ": " + i);

}

}

}

}

方式三:实现Callable 接口

实现Callable 接口,该接口是JDK 5.0 中新增的。

步骤

1.创建一个实现Callable 的实现类

2.实现call()方法,将此线程需要执行的操作声明到call()方法中,注意该方法是有返回值的。

3.创建Callable接口实现类的对象

4.将此Callable实现类的对象(numThread)传递FutureTask构造其中,创建FutureTask对象。

5.将FutureTask创建的对象,传递到Thread构造器中,在start该线程。

6.如果关心线程中call()方法的返回值,则可以用个futureTask.get() 来抓取返回值。

例如:如下代码用于计算0~100以内,所有偶数的和

package com.jerry.thread10;

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutionException;

import java.util.concurrent.FutureTask;

public class ThreadCallableTest {

public static void main(String[] args) {

//3.创建Callable接口实现类的对象

NumThread numThread = new NumThread();

//4.将此Callable实现类的对象(numThread)传递FutureTask构造其中,创建FutureTask对象。

FutureTask futureTask = new FutureTask(numThread);

//5.将FutureTask创建的对象,传递到Thread构造器中,在start该线程。

new Thread(futureTask).start();

//6.如果关心线程中call方法的返回值,则可以用个futureTask.get() 来抓取返回值。

try {

//拿到其返回值

Integer sum = futureTask.get();

System.out.println("总和为: " + sum);

} catch (InterruptedException e) {

e.printStackTrace();

} catch (ExecutionException e) {

e.printStackTrace();

}

}

}

//1.创建一个实现Callable 的实现类

class NumThread implements Callable {

//2.实现call方法,将此线程需要执行的操作声明到call方法中,注意该方法是有返回值的。

@Override

public Integer call() throws Exception {

int sum = 0;

for (int i = 0; i <= 100; i++) {

if (i % 2 == 0) {

System.out.println(i);

sum += i;

}

}

return sum;

}

}

注意: 如何理解Callable 接口更强大?

call() 方法是有返回值得。

call() 可以抛出异常,被外面的操作捕获,获取异常信息。

Callable 中是支持泛型的,这个泛型就是用futureTask.get()的返回值。

方式四:使用线程池(ThreadPool)

1、使用线程池的好处

1.提高了响应速度(减少了创建线程的时间)

2.降低资源消耗(重复利用线程池中的线程,不需要每次都创建)

3.便于管理,如可设置如下属性管理线程池

corePoolSize 线程池大小

maximumPoolSize 最大线程数

keepAliveTime 线程没有任务时,最多保持多长时间后会终止

2、步骤

这里我们只演示了通过Runnable 实现接口方式构建run方法

1.创建一个固定大小的线程池

2.设置线程池属性

3.使用execute执行当前线程,excute适合用于Runnable方式,当线程方法是Callable时要用submit

4.使用shutdown方法关闭当前线程,线程池不用了,则关闭当前线程。

例如:如下代码创建了固定可容纳10个线程的线程池,当中有两个线程,分别输出奇数和偶数

package com.jerry.thread10;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.ThreadPoolExecutor;

public class ThreadPoolTest {

public static void main(String[] args) {

//1.创建一个固定大小的线程池

ExecutorService service = Executors.newFixedThreadPool(10);

//2.设置线程池属性

ThreadPoolExecutor executor1 = (ThreadPoolExecutor) service;

executor1.setCorePoolSize(10);

//3.执行当前线程,适合用于Runnable,Callable 要用submit

service.execute(new NumThread1());//执行线程1,用于输出偶数

service.execute(new NumThread2());//执行线程2,用于输出奇数

//4.关闭当前线程,线程池不用了,则关闭当前线程

service.shutdown();

}

}

class NumThread1 implements Runnable {

//输出偶数

@Override

public void run() {

for (int i = 0; i <= 100; i++) {

if (i % 2 == 0) {

System.out.println(Thread.currentThread().getName() + ": " + i);

}

}

}

}

class NumThread2 implements Runnable {

//输出奇数

@Override

public void run() {

for (int i = 0; i <= 100; i++) {

if (i % 2 != 0) {

System.out.println(Thread.currentThread().getName() + ": " + i);

}

}

}

}

二、 线程的中的常用方法

线程中的常用方法如下

start();启动当前线程,调用当前线程中的run() 方法

run(); 通常需要重写Thread 类中的此方法,将创建的线程要执行的操作声明再此方法中

currentThread();静态方法,返回执行当前代码的线程

getName();获取当前线程的名字,也可以根据构造器传参方式命名

setName();设置当前线程的名字

yield(); 释放CPU 的执行权

join(); 当前线程先暂停,切换到另一个线程,等另一个线程执行完,才能执行当前线程

stop(); 已过时。用于强制结束当前线程

sleep(long millitime);线程挂起多少毫秒

三、 线程的优先级

说明:线程是分优先级的,线程的优先级由1~10,分为10个等级,数字越大,优先级越高。

可以看到优先级在Thread类中定义了一个枚举,具体如下:

MIN_PRIORITY = 1;

NORM_PRIORITY = 5;

MAX_PRIORITY = 10;

如何设置优先级?

可以通过thread.setPriority(1~10) 来设置优先级的高低,其中thread 对象为继承自Thread实现的对象。

如下代码演示如何去设置线程的优先级

public class ThreadTest {

public static void main(String[] args) {

ThreadPriority thread = new ThreadPriority("Sub Thread: 1");

//设置优先级为最大10

thread.setPriority(Thread.MAX_PRIORITY);

thread.start();

for (int i = 0; i < 100; i++) {

System.out.println(Thread.currentThread().getName() + " : " + i);

}

}

}

class ThreadPriority extends Thread {

ThreadPriority(String name) {

super(name);

}

@Override

public void run() {

for (int i = 0; i < 100; i++) {

if (i % 2 == 0) {

System.out.println(Thread.currentThread().getName() + " : " + i);

}

}

}

}

注意:

设置了高优先级的线程,只是优先去执行它,并不是说他必须全部执行完,才会切换到低优先级的线程。

从概率上来讲,CPU 优先执行高优先级的线程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值