Java Java中三种常见的创建线程形式

1.继承Thread类,重写该类的run()方法。
先创建一个线程类对象,调用start方法启动新线程。此处调用start方法不代表线程立马运行,start方法只是把该线程加入到操作系统的任务队列中,当被操作系统的任务调度机制调度到后才执行。
注意:如果使用线程对象调用run方法,则此时run方法相当于对象的普通方法。此处就没有创建线程,依然在原有线程中

public class MyThread extends Thread {
   

	@Override
	public void run() {
   
		for (int i = 0; i < 100; i++) {
   
			System.out.println("自定义线程," + i);
		}
	}
}
public class Test {
   
	public static void main(String[] args) {
   
		MyThread myThread1 = new MyThread();
		MyThread myThread2 = new MyThread();
		myThread1.start();
		myThread2.start();

		for (int i = 0; i < 100; i++) {
   
			System.out.println("main线程," + i);
		}
	}
}

2.实现Runnable接口,并重写该接口的run()方法
该run()方法同样是线程执行体,创建Runnable实现类的实例,并以此实例作为Thread类的target来创建Thread对象,该Thread对象才是真正的线程对象。

public class MyThread implements Runnable {
   
	@Override
	public void run() {
   
		for (int i = 0; i < 100; i++) {
   
			System.out.println(Thread.currentThread().getName() + "," + i);
		}
	}
}
public class Test {
   

	public static void main(String[] args) {
   
		// 没有start方法
		MyThread myThread1 = new MyThread();
		MyThread myThread2 = new MyThread();

		// 创建一个线程对象
		Thread t1 = new Thread(myThread1);
		t1.start();
		Thread t2 = new Thread(myThread2);
		t2.start();
		for (int i = 0; i < 100; i++) {
   
			System.out.println(Thread.currentThread().getName() + "," + i);
		}
	}
}

3.使用Callable和Future接口创建线程。
先自定义类实现Callable接口;实现call方法,该方法有返回值类型,使用FutureTask类来包装Callable实现类,以FutureTask对象作为Thread对象的target来创建线程。
FutureTask类实际上是同时实现了Runnable和Future接口,由此才使得其具有Future和Runnable双重特性。通过Runnable特性,可以作为Thread对象的target,而Future特性,使得其可以取得新创建线程中的call()方法的返回值。这是一种适配器模式。

public class MyThread implements Callable<String> {
   

	@Override
	public String call() throws Exception {
   
		for (int i = 0; i < 100; i++) {
   
			System.out.println(Thread.currentThread().getName() + "," + i);
			Thread.sleep(10);
		}
		return "100";
	}
}
public class Test {
   

	public static void main(String[] args) throws InterruptedException, ExecutionException {
   
		// 没有start方法
		MyThread myThread1 = new MyThread();
		MyThread myThread2 = new MyThread();
		FutureTask<String> future1 = new FutureTask(myThread1);
		FutureTask<String> future2 = new FutureTask(myThread2);

		// 创建一个线程对象
		Thread t1 = new Thread(future1);
		t1.start();
		Thread t2 = new Thread(future2);
		t2.start();
		Thread.sleep(2000);
		for (int i = 0; i < 100; i++) {
   
			System.out.println(Thread.currentThread().getName() + "," + i);
		}
	}
}

4、面试说以上三种就够了,但还有第四种线程池的方式。

Java通过Executors提供四种线程池,分别为:

  1. newSingleThreadExecutor (老板就是工人,整个工厂只有一个工人)。创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
  2. newFixedThreadPool (全部是正式工)。创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
  3. newScheduledThreadPool 。创建一个可定期或者延时执行任务的定长线程池,支持定时及周期性任务执行。
  4. newCachedThreadPool (全部是临时工)。创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
全部评论

相关推荐

孤寡孤寡的牛牛很热情:为什么我2本9硕投了很多,都是简历或者挂,难道那个恶心人的测评真的得认真做吗
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务