您的位置:首页 > 编程语言 > Java开发

java多线程与并发之创建线程的几种方式

2018-01-20 10:25 495 查看

1、继承Thread类方法

public class Demo1 extends Thread{

@Override
public void run() {
//判断标志
while(true) {
System.out.println(getName()+"-->线程执行了....");
}
}

public static void main(String[] args) {
Demo1 d1 = new Demo1();
d1.start();
}

}

2、实现Runnable接口

/**
* Runnable 作为线程任务存在
* @author abel
*/
public class Demo2 implements Runnable {
@Override
public void run() {
while(true) {
System.out.println("线程开始执行......");
}
}

public static void main(String[] args) {
Thread t = new Thread(new Demo2());

t.start();
}
}

3、采用匿名内部类的方式创建线程(使用一次的时候使用)

public class Demo3 {

    public static void main(String[] args) {
        //1)通过thread子类创建匿名内部类
        new Thread() {
            public void run() {
                System.out.println("线程开始执行......");
            };
        }.start();
        
        //2)通过线程任务的方式创建匿名内部类
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程开始执行......");
                
            }
        }).start();
    }
}

扩展:采用匿名内部类的方式同时采用上面两种方式会执行子类的run方法

public class Demo3 {

public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("实现runnable接口的run方法......");
}
}) {
public void run() {
System.out.println("执行的子类的run方法......");
};
}.start();
}
}

结果:
执行的子类的run方法......

原因:因为Thread类在new的时候,虽然传了Runnable也就是源码中的target已经传到init中了,并且在init中赋给了Thread类的target属性(此时target指向的是参数中的runnable接口),之后在调用start()启动的时候,就去调用了run()方法
public void run() {
if (target != null) {
target.run();
}
}

但子类重写了run(),所以最后执行的是子类的run()方法,而没调用父类的run()。

4、有返回值的创建方式(实现Callable接口)

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

//参数使用泛型,以Integer为例
public class Demo4 implements Callable<Integer>{

@Override
public Integer call() throws Exception {
System.out.println("正在执行方法体......");
Thread.sleep(3000);
return 100;
}

public static void main(String[] args) throws InterruptedException, ExecutionException {
Demo4 d = new Demo4();
//FutureTask是继承Runnable,是对Runnable的封装,所以需要包装到Thread类中执行
FutureTask<Integer> task = new FutureTask<>(d);

//包装到Thread类中进行执行
Thread t = new Thread(task);
t.start();

System.out.println("执行别的任务....");
//获取线程执行结果
Integer i = task.get();
System.out.println("线程执行结果是:"+i);
}
}

执行结果:
执行别的任务....
正在执行方法体......
线程执行结果是:100

5、定时器的方式创建线程

public class Demo5 {
public static void main(String[] args) {
Timer timer = new Timer();
//TimerTask是一个抽象类,实现的是runnable接口
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("执行线程任务......");
}
}, 0, 1000);
}
}

有很多schedule可选
注意:方法体中出现异常后,该定时任务直接结束

6、使用线程池创建线程

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Demo6 {
    public static void main(String[] args) {
        //创建线程池,有多种可选线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 100; i++) {
            threadPool.execute(new Runnable() { //执行一次
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+"-->线程执行......");
                    
                }
            });
        }
        //停掉当前线程池
        threadPool.shutdown();
    }
}

执行结果:

pool-1-thread-1-->线程执行......
pool-1-thread-5-->线程执行......
pool-1-thread-2-->线程执行......
pool-1-thread-3-->线程执行......
pool-1-thread-6-->线程执行......
pool-1-thread-4-->线程执行......
pool-1-thread-9-->线程执行......
pool-1-thread-7-->线程执行......
pool-1-thread-8-->线程执行......
pool-1-thread-10-->线程执行......

7、采用lambda表达式(函数式)实现

import java.util.Arrays;
import java.util.List;

public class Demo7 {
public int add(List<Integer> values) {
//		values.parallelStream().forEach(System.out :: println);
//parallelStream是个并行的
return values.parallelStream().mapToInt(i -> i).sum();
}
public static void main(String[] args) {

List<Integer> values = Arrays.asList(10,20,30,40);
int sum = new Demo7().add(values);
System.out.println("计算结果是:"+sum);
}
}

执行结果:

30
40
10
20
计算结果是:100
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java thread
相关文章推荐