(1)线程,进程,程序
进程:动态,程序运行的基本单位,由CPU,Data,Code组成
线程:任务调度和执行多个内存资源共享内存空间和系统资源
程序:静态代码
线程和进程的区别:
线程 | 进程 |
---|---|
线程是执行和调度 | 资源分配的单位 |
同一线程共享数据和数据空间,线程切换花费时间少 | 进行有独立的代码和数据空间,进程切换有较大的开销 |
在同一应用中有多个线程顺序流执行 | 操作系统中能同时运行多个进程 |
线程是进程的一部分,线程是轻量级进程 | 一个进程拥有多个线程,执行过程不是一条线,而是多条线程共同完成的 |
线程组只能共享资源 | 系统在运行时为每一个进行分配不同的内存区域 |
(2)启动线程有三种方式:
(1)继承Thread类 重写run方法,start()启动线程
public class Threaddemo extends Thread{
@Override
public void run() {
for (int i = 0; i <20; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+i);
}
}
public static void main(String[] args) {
Threaddemo threaddemo = new Threaddemo();
threaddemo.start();
for (int i = 0; i < 20; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+i);
}
}
}
(2)实现Runnable接口,其实Thread类也是实现Runnable接口,重写run方法,然后new Thread(实例化对象).start()方式启动线程
public class MyThread implements Runnable {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+i);
}
}
public static void main(String[] args) {
MyThread thread = new MyThread();
new Thread(thread).start();
}
}
(3)实现Callable接口,Callable可以定义返回会,重写run方法会抛出异常,创建对象,使用线程池的方式启动线程,最终关闭服务
public class CallableDemo implements Callable<Boolean> {
@Override
public Boolean call() throws Exception {
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName()+"------"+i);
}
return true;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
CallableDemo demo = new CallableDemo();
//Callable启动线程的方式,
// 1:创建服务
ExecutorService service = Executors.newFixedThreadPool(3);
// 2:提交执行
Future<Boolean> s1 = service.submit(demo);
Future<Boolean> s2 = service.submit(demo);
Future<Boolean> s3 = service.submit(demo);
// 3:获取结果
Boolean aBoolean1 = s1.get();
Boolean aBoolean2 = s1.get();
Boolean aBoolean3 = s1.get();
// 4:关闭服务
service.shutdownNow();
}
}
(3)线程停止方式:
(1)调用Thread中内部方法stop,不建议
(2)线程执行完,自动停止
(3)设置flag,让线程停止
public class ThreadStopDemo extends Thread{
//设置flag标志位
private boolean flag = true;
@Override
public void run() {
while (flag){
System.out.println(Thread.currentThread().getName());
}
}
public void doStop(){
this.flag = false;
}
public static void main(String[] args) {
ThreadStopDemo threadStopDemo = new ThreadStopDemo();
threadStopDemo.start();
for (int i = 0; i < 1000; i++) {
System.out.println(Thread.currentThread().getName());
if (i==900){
threadStopDemo.doStop();
}
}
}
}
(4)线程sleep
使用场景:
(1)设置延迟
(2)计时
public class SleepDemo extends Thread{
@Override
public void run() {
int i=10;
while (true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i--);
if (i<0){
break;
}
}
}
public static void main(String [] args){
SleepDemo demo = new SleepDemo();
demo.start();
}
public class SleepDelayDemo{
public static void main(String[] args) {
Date date = new Date(System.currentTimeMillis());
while (true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String format = new SimpleDateFormat("HH:mm:ss").format(date);
System.out.println(format);
date = new Date(System.currentTimeMillis());
}
}
}
(5) yield
线程礼让一次
(6) join
一个线程中使用执行join,会执行另外一个线程当另外一个线程执行完,再来执行这个线程
(7) Status
线程的观测状态
(8) setPriority 和getPriority
设置优先级和获得优先级
设置优先级等级1-10,越高执行的概率越大,实际执行需要CPU进行调度,认为不能控制。
(9)线程的生命周期
线程的声明周期:
(10)sleep和wait的区别
(1)sleep是Thread静态方法,而wait是Object内部的函数
(2)sleep会抛出异常,而wait不会
(3)sleep的应用场景更加多,而wait一样用在同步代码块或同步方法中
(4)sleep过程中不会释放对象的锁,阻塞到达时间后进入就绪状态,而wait等待过程中会释放锁,只有其他调用notify唤醒其线程,才会进入就绪状态