java实现多线程的三种方法,java实现多线程的两种方式
00-1010并发并行进程和线程java的threads java多线程机制java的主线程创建线程的生命周期(三种类型)继承Thread类实现线程创建实现Runnable接口实现Callable接口线程池
00-1010并发:在操作系统中,指的是几个程序都处于从启动到完成的时期,这些程序都运行在同一个处理器上,但任何时候都只有一个程序在该处理器上运行。
并行:一组程序以独立的、异步的速度执行,这些程序都是一起执行的,无论从微观还是宏观层面。
对比:并发是指:中两个或两个以上的程序在同一时间段内执行,时间上有重叠(宏观上是同时执行,微观上仍然是顺序执行)。
00-1010进程是程序在计算机中一个数据集上的运行活动,是系统中资源分配和调度的基本单位,是操作系统结构的基础。
线程(英文:Thread)是操作系统可以调度操作的最小单位。它包含在流程中,是流程中的实际操作单元。线程是指流程中控制流的单个序列。多个线程可以在一个进程中并发,每个线程并行执行不同的任务。
目录
00-1010多线程是指一个应用同时有几个执行器,根据几个不同的执行线索协同工作的情况。Java多线程机制,使得程序员可以轻松开发出具有多线程功能的强大应用,并且可以同时处理多个任务。java内置了对多线程的支持,Java虚拟机可以从一个线程快速切换到另一个线程。这些线程的交替执行为每个线程提供了使用cpu资源的机会。
00-1010每个java程序都包含一个线程,这个线程就是主线程。Java应用程序都是从main类的main方法执行的。当jvm加载代码,找到炫耀的方法,就会启动一个线程,这个线程就是主线程,负责执行main方法。如果在主线程中创建了其他线程,它会在主线程和其他线程之间来回切换,直到所有其他线程结束才会结束主线程。
并发与并行
奔跑
线程创建后,只占用内存资源。JVM管理的线程中没有新创建的线程。只有在这个线程调用start()方法之后,JVM才知道队列中有一个新线程在等待cpu调用。
中断原因(4种)
将jVM的cpu资源切换到其他线程。
当一个线程正在使用它的cpu时,它执行sleep(int millsecond)方法将当前线程置于睡眠状态。调用此方法后,它会立即放弃cpu,在参数millsecond指定的毫秒后,它会重新加入队列,等待cpu。
-在cpu的使用过程中,执行wait()方法,使当前进程进入等待状态。这个等待睡眠()就不一样了。这种等待需要其他线程调用notify()方法来唤醒线程,这个线程会重新进入队列等待cpu。
当一个线程在使用cpu时,它执行一些操作进入阻塞状态,比如(读、写、打印等。).只有完成了这些阻塞原因,这个线程才会进入队列等待cpu。
进程与线程
00-1010一个是创建类继承线程类,可以重用!一种是直接使用匿名内部类继承。此类型只能使用一次。每次使用都要重新创建run()方法,定义好之后调用start()方法,将这个线程调入线程队列等待调用。下面我们用匿名内部类创建一个100以内的奇数线程,用类继承Thread类打印100以内的偶数线程。
包你好;public class Hello { public static void main(String[]args){ thread 1 thread 1=new thread 1();Thread Thread=new Thread(){ @ Override public void run(){ for(int I=0;i 100I) {if (i% 2==1) {//打印线程名,从0开始。
System.out.println(Thread.currentThread().getName() + ":" + i); } } } }; thread1.start(); thread.start(); }}class Thread1 extends Thread{ @Override public void run() { super.run(); for(int i=0;i<100;i++){ if (i%2==0){ System.out.println(Thread.currentThread().getName()+":"+i); } } }}方法说明
start()启动当前线程;调用当前线程的run()方法
run():需要重写Thread类中的此方法,将创建线程需要执行的操作声明在此方法中
currentThread():返回执行当前代码的线程
getName():获取当前线程的名字
setName(String name):设置当前线程的名字
yield():释放当前CPU的执行权
join():在线程a中调用线程b的join(),此时线程a就进入阻塞状态,直到线程b完全执行完之后,线程a在结束阻塞状态
sleep(int millitime):让当前线程睡眠指定的millitime毫秒。在指定的millitime毫秒时间内,当前进程是阻塞状态
isAlive():判断当前线程是否存活(线程执行完之前都是存活的)
实现Runnable接口
我们还是创建两个线程,一个打印奇数,一个打印偶数,但是有一个线程每次调用会睡眠(阻塞)10ms。
使用实现接口Runnable方法,必须重写run()方法。
package hello;public class Hello { public static void main(String[] args) { Thread thread = new Thread(new MyThread1()); /* Thread thread = new Thread(new MyThread1()); 就相当于 ,就是创建实现类的对象,再把这个对象用Thread()构造器的方法创建 MyThread1 myThread1 = new MyThread1(); Thread thread = new Thread(myThread1); */ Thread thread1 = new Thread(new MyThread2()); thread.start(); thread1.start(); }}class MyThread1 implements Runnable{ @Override public void run() { for(int i=0;i<100;i++) { if (i % 2 == 1) { System.out.println(Thread.currentThread().getName() + ":" + i); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } }}class MyThread2 implements Runnable{ @Override public void run() { for(int i=0;i<100;i++) { if (i % 2 == 0) { System.out.println(Thread.currentThread().getName() + ":" + i); } } }}
开发中,优先选择实现Runnable接口的方式创建线程
原因:
实现Runnable接口的方式没有类的单继承性的局限性(一个类只能继承一个父类,继承了Thread类就不能在继承其他类了)
实现Runnable接口的方式更适合来处理多个线程之间有共享数据的情况
实现Callable接口
Runnable接口是没有返回值的 Callable有返回值,可以抛出异常
Thread类并不接受Callable对象。可以使用FutureTask类实现Runnable接口和Future接口
Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果。必要时可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果。
Java的类是单继承的设计,如果采用继承Thread的方式实现多线程,则不能继承其他的类,采用接口能够更好的实现数据共享
FutureTask有两个构造函数,一个以Callable为参数,另外一个以Runnable为参数。
我理解的就是通过FutureTask把Callable变成通过Runnable接口创建的,因为FutureTask继承了Runnable接口。主要原因是Thread类不接受Callable创建,但是接受Runnable创建的线程。
package hello;import java.util.concurrent.Callable;import java.util.concurrent.FutureTask;public class Hello { public static void main(String[] args) throws Exception { MyThread1 myThread1 = new MyThread1(); FutureTask<Integer> futureTask = new FutureTask<>(new MyThread1()); new Thread(futureTask).start();//开启线程 System.out.println(futureTask.get());//获取返回值 }}class MyThread1 implements Callable<Integer> { @Override public Integer call() throws Exception { int count = 0; for (int i = 1;i<100;i++){ if (i%3==0){ count++; } } return count; }}
线程池
线程池的执行过程
实例
package hello;import java.util.concurrent.*;public class Hello { public static void main(String[] args) throws Exception { //创建线程池 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 4, 5, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(2), new ThreadFactory() { @Override public Thread newThread(Runnable r) { Thread thread = new Thread(r); thread.setName("myThread"); return thread; } }, new ThreadPoolExecutor.AbortPolicy()); //threadPoolExecutor.submit(); threadPoolExecutor.execute(new MyThread());//提交任务 threadPoolExecutor.shutdown();//关闭线程池 }}class MyThread implements Runnable{ @Override public void run() { for (int i=0;i<10;i++){ System.out.println(i); } }}
以上就是详解Java实现多线程的三种方式的详细内容,更多关于Java多线程的资料请关注盛行IT其它相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。