在Java中实现并发有四种方法
- 继承Thread类
- 实现Runable接口
- 实现Callable接口,FutureTask辅助实现
- 使用线程池创建(先不写,因为没看懂呜呜呜)
1.继承Thread类
这个是创建线程的最简单的一个做法,创建一个类,然后继承Thread类,重写里面的run()方法,把自己的业务逻辑在这个函数中实现。 最后让这个线程strat(),我写了一个多进程实现从1加到1000的的一段Demo
// 使用继承Thread类来创建线程
class AddThread extends Thread{
private int start, end;
private int sum = 0;
public AddThread(String name, int start, int end) {
super(name);
this.start = start;
this.end = end;
}
@Override
public void run() {
System.out.println(this.getName() + "is start");
for (int i = start; i <= end; i++) {
sum+=i;
}
System.out.println(this.getName() + "is end");
}
public int getSum() {
return sum;
}
}
public class CreateThread1{
public static void main(String[] args) throws InterruptedException{
int start1 = 1;
int end1 = 500;
int start2 = 501;
int end2 = 1000;
AddThread thread1 = new AddThread("thread1", start1, end1);
AddThread thread2 = new AddThread("thread2", start2, end2);
thread1.start();
thread2.start();
thread1.join();
thread2.join();
int sum = thread1.getSum()+thread2.getSum();
System.out.printf("sum of 1 to 1000 is %d
", sum);
}
}
2.实现Runable接口
实现一个接口,那么就要是创建一个类实现这个接口的方法,我们必须实现一个run()方法,同时检测InterruptedException线程中断异常。最后创建一个线程,将这个实现Runable接口的类的对象作为参数添加。
// 使用实现Runable接口来实现创建线程
class ThreadDemo implements Runnable{
public ThreadDemo() {
System.out.println("Create " + Thread.currentThread().getName());
}
//必须实现run方法
@Override
public void run() {
System.out.println("Runing " + Thread.currentThread().getName());
try {
for (int i = 0; i < 4; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
Thread.sleep(50);;
}
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " interrupted.");
}
System.out.println(Thread.currentThread().getName() + " exiting.");
}
}
public class CreateThread2 {
public static void main(String[] args) {
ThreadDemo run1 = new ThreadDemo();
Thread thread1 = new Thread(run1, "thread1");
thread1.start();
ThreadDemo run2 = new ThreadDemo();
Thread thread2 = new Thread(run2, "thread2");
thread2.start();
}
}
3.实现Callable接口辅助FutureTask来创建线程
和第二种方法不同的是,实现了这个Callable接口的类需要实现的方法是call()而不是run(),而且call()是可以有返回值的,然后使用泛型类FutureTask创建创建Thread
// 使用实现Callable接口辅助FutureTask来创建线程
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
class CallableThread implements Callable<String> {
private boolean flag;
public CallableThread(boolean f) {
this.flag = f;
}
@Override
public String call() throws Exception {
for (int i = 1; i <= 5; i++) {
//执行输出5次,因为call方式是阻塞方式的,所以这五次输出应该是连续
System.out.println(Thread.currentThread().getName() + " :" + i);
}
return flag == true ? "flag is true" : "flag is false";
}
}
public class CreateThread3 {
public static void main(String[] agrs) {
CallableThread ct1 = new CallableThread(false);
CallableThread ct2 = new CallableThread(true);
CallableThread ct3 = new CallableThread(false);
//FutureTask实现了Runable和Future接口
FutureTask<String> task1 = new FutureTask<>(ct1);
FutureTask<String> task2 = new FutureTask<>(ct2);
FutureTask<String> task3 = new FutureTask<>(ct3);
Thread thread1 = new Thread(task1); //创建第一个线程
Thread thread2 = new Thread(task2); //创建第二个线程
Thread thread3 = new Thread(task3); //创建第三个线程
for(int i = 1; i <= 10; i++){
System.out.println(Thread.currentThread().getName()+" :"+i);
if(i == 5){
try{
thread1.start(); //启动第一个线程
System.out.println("task1 get value: "+task1.get());
thread2.start(); //启动第二个线程
System.out.println("task2 get value: "+task2.get());
thread3.start(); //启动第三个线程
System.out.println("task3 get value: "+task3.get());
}catch(Exception e){
e.printStackTrace();
}//每个线程的task调用get方法的时候都会阻塞程序,所以会连续输出5次后执行后面的程序
}
}
}
}