创建线程的三种模式
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
进程是对运行时程序的封装是系统进行资源调度和分配的基本单位实现了操作系统的并发。
线程是进程的子任务是CPU调度和分派的基本单位实现了进程内部的并发。
线程在进程下运行。
进程之间不会影响。
不同进程很难共享数据。
同进程下的线程数据很容易共享。
进程使用内存地址可以限定用量。
继承Thread类
重写run方法
public class Mythread extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName()+"执行第"+i+"次..");
}
}
}
测试
import java.util.*;
class Test{
public static void main(String[] args) {
//创建线程
Mythread t1=new Mythread();
Mythread t2=new Mythread();
Mythread t3=new Mythread();
//设置线程名
t1.setName("线程1");
t2.setName("线程2");
t3.setName("线程3");
//启动线程
t1.start();
t2.start();
t3.start();
}
}
控制台输出片段
线程交替执行而并非顺序执行说明它们使用同一资源属于同一进程。
实现Runnable接口
并重写run方法
public class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try{
//sleep会发生异常要显示处理
Thread.sleep(20);//暂停20毫秒
}catch (Exception e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "执行了"+i+"次..");
}
}
}
sleep()
使当前正在执行的线程暂停指定的毫秒数也就是进入休眠的状态。
需要注意的是sleep 的时候要对异常进行处理。
测试
import java.util.*;
class Test{
public static void main(String[] args) {
//创建Runnable
MyRunnable myRunnable = new MyRunnable();
//创建线程,设置名称
Thread t1=new Thread(myRunnable,"线程1");
Thread t2=new Thread(myRunnable,"线程2");
Thread t3=new Thread(myRunnable,"线程3");
//启动线程
t1.start();
t2.start();
t3.start();
}
}
控制台输出片段
join()等待这个线程执行完才会轮到后续线程得到cpu的执行权使用这个也要抛出异常。
测试
import java.util.*;
class Test{
public static void main(String[] args) {
//创建Runnable
MyRunnable myRunnable = new MyRunnable();
//创建线程,设置名称
Thread t1=new Thread(myRunnable,"线程1");
Thread t2=new Thread(myRunnable,"线程2");
Thread t3=new Thread(myRunnable,"线程3");
//启动线程
t1.start();
try {
t1.join(); //等待t1执行完才会轮到t2t3抢
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
t3.start();
}
}
控制台输出片段
setDaemon()
将此线程标记为守护线程准确来说就是服务其他的线程像 Java 中的垃圾回收线程就是典型的守护线程。
import java.util.*;
class Test{
public static void main(String[] args) {
//创建Runnable
MyRunnable myRunnable = new MyRunnable();
//创建线程,设置名称
Thread t1=new Thread(myRunnable,"线程1");
Thread t2=new Thread(myRunnable,"线程2");
Thread t3=new Thread(myRunnable,"线程3");
t1.setDaemon(true);
t2.setDaemon(true);
//启动线程
t1.start();
t2.start();
t3.start();
}
}
控制台输出片段
如果其他线程都执行完毕main 方法主线程也执行完毕JVM 就会退出也就是停止运行。如果 JVM 都停止运行了守护线程自然也就停止了。
实现Runable接口比继承Thread方法好避免了Java单继承的局限性适合多个相同的程序代码去处理同一资源的情况把线程、代码和数据有效的分离更符合面向对象的设计思想。
实现Callable接口
重写call()方法这种方式可以通过FutureTask获取任务执行的返回值
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class CallerTask implements Callable<String > {
@Override
public String call() throws Exception {
return "正在运行..";
}
public static void main(String[] args) {
//创建异步任务
FutureTask<String>task=new FutureTask<>(new CallerTask());
//启动线程
new Thread(task).start();
try{
//等待执行完成返回获取结果
String res=task.get();
System.out.println(res);
}catch (Exception e) {
e.printStackTrace();
}
}
}
控制台输出
重写run方法原因
封装被线程执行的代码。
run()和start()区别
run():封装线程执行的代码直接调用相当于调用普通方法。
start()启动线程然后由JVM 调用此线程的run() 方法。
Java线程周期