Java创建线程实现并发

在Java中实现并发有四种方法

  1. 继承Thread类
  2. 实现Runable接口
  3. 实现Callable接口,FutureTask辅助实现
  4. 使用线程池创建(先不写,因为没看懂呜呜呜)

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次后执行后面的程序
			}
		}
	}
}
原文地址:https://www.cnblogs.com/yfc0818/p/11072584.html