目录
一.线程与创建线程方式简介
二.Thread继承
三.实现Runnable接口
四.Callable接口
五.使用线程池
一.线程与创建线程方式简介
线程与进程的区别:
1、一个进程至少包含一个线程
2、比如电脑上QQ,运行起来就是一个进程,QQ可以聊天同时也可以传文件,聊天和传文件就是两个不同的线程。
软件必须运行起来才算进程。
对于同一个CPU来讲,在某一刻,只能执行一个线程,多个线程频发切换,给人一种多线程操作的假象。
多线程之间存在相互抢占CPU资源的情况。
创建线程的四种方式:
1、Thread 继承
2、实现Runnable 接口
3、Callable 接口
4、使用线程池
二.Thread继承
代码如下:
class MyThread extends Thread{// Ctrl + o// 展示所有的可以重写的方法@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println("数据:"+i);}}
}
public class _01继承Thread类{public static void main(String[] args) {// 在Main方法中,启动了一个子线程,子线程什么时候工作MyThread thread = new MyThread();thread.start();// 启动一个线程,调用start方法,不要调用run方法// 一个线程类,是可以创建多个不同的子线程的MyThread thread2 = new MyThread();thread2.start();// 启动一个线程,调用start方法,不要调用run方法// 主线程,直接运行代码 会出现子线程和主线程抢占资源的情况for (int i = 10; i < 100; i++) {System.err.println("Main:"+i);}}
}
运行结果:
三.实现Runnable接口
代码:
class A implements Runnable{@Overridepublic void run() {for (int i = 0; i < 1000; i++) {System.out.println(Thread.currentThread().getName()+":"+i);}}
}
public class _02Runnable接口 {/*** 多线程创建的第二种方式,使用 Runnable接口* 该接口还需要传递给Thread类才能启动,否则自己启动不了** 两种方式:推荐使用第二种* 1、Thread类是一个线程类,它只需要管理好线程就行了,不需要管业务怎么写* 2、具体的业务可以交给Runnable接口实现* 3、java是单继承的,继承了Thread,就无法继承别的类了,但是可以实现多个接口。*/public static void main(String[] args) {A a = new A();new Thread(a).start();// Runnable接口本身就是一个函数式接口,就可以使用lambda表达式,代码可以简化为如下:new Thread( ()-> {for (int i = 0; i < 1000; i++) {System.out.println(Thread.currentThread().getName()+":"+i);}}).start();for (int i = 0; i < 1000; i++) {System.err.println(Thread.currentThread().getName()+":"+i);}}
}
运行结果:
四.Callable接口
代码:
class MyCall implements Callable<Integer>{@Overridepublic Integer call() throws Exception {return 200;}
}class MyRun implements Runnable{@Overridepublic void run() {System.out.println("我是子线程....");}
}
public class _03Callable接口 {public static void main(String[] args) throws ExecutionException, InterruptedException {FutureTask<Integer> futureTask = new FutureTask<>(new MyCall());new Thread(futureTask,"计算线程").start();Integer i = futureTask.get();System.out.println(i);// --------------------------------------new Thread(new MyRun()).start();// ------------------使用callable 模拟 子线程进行大量计算并返回结果------------------FutureTask<Integer> f1 = new FutureTask<>(()->{System.out.println(Thread.currentThread().getName()+" come in callable");TimeUnit.SECONDS.sleep(4);return 1024;});FutureTask<Integer> f2 = new FutureTask<>(()->{System.out.println(Thread.currentThread().getName()+" come in callable");TimeUnit.SECONDS.sleep(4);return 2048;});new Thread(f1,"线程一:").start();new Thread(f2,"线程二:").start();while(!f1.isDone()){System.out.println("f1 wait中.....");}while(!f2.isDone()){System.out.println("f2 wait中.....");}// 其实 get 获取不到值会一直阻塞,直到获取到值为止int a = f1.get();int b = f2.get();System.out.println(a+b);}
}
运行结果:
五.使用线程池
代码:
public class _04线程池 {public static void main(String[] args) {ExecutorService threadPool = new ThreadPoolExecutor(2,5,2L,TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(3),Executors.defaultThreadFactory(),//new ThreadPoolExecutor.AbortPolicy()//new ThreadPoolExecutor.CallerRunsPolicy()//new ThreadPoolExecutor.DiscardOldestPolicy()new ThreadPoolExecutor.DiscardOldestPolicy());//10个顾客请求try {for (int i = 1; i <= 10; i++) {threadPool.execute(() -> {System.out.println(Thread.currentThread().getName() + "\t 办理业务");});}} catch (Exception e) {e.printStackTrace();} finally {threadPool.shutdown();}}
}
运行结果: