线程和进程的区别?
进程是系统进行资源分配和调度的一个独立单位。最小执行单元是线程。
线程是进程的一个实体,一个进程中拥有多个线程,线程之间共享地址空间和其他资源。
线程上线文的切换比进程上下文切换要快很多。
进程切换时,涉及到当前进程CPU环境的保存和新被调度运行进程的CPU环境的设置。
线程切换仅需要保存和设置少量的寄存器内容,不涉及存储管理方面的操作。
创建线程的方式:
继承Thread类,重写run方法;
实现Runnable接口;
实现Callable接口;
通过线程池启动线程;
lamda表达式直接new Thread(() -> {//业务逻辑}).start();
sleep:使当前正在执行的线程以指定的毫秒数暂停,具体取决于系统定时器和调度程序的精度和准确性。会使线程变为TimedWaiting状态,不会释放锁,当线程结束睡眠时,会变为就绪状态,等待运行。
yield:暂停当前正在运行的线程(及放弃当前拥有的cpu资源),并执行其他线程。yield()做的是让当前运行线程回到可运行状态,以达到允许具有相同优先级的其他线程获得运行机会。目的,让相同优先级的线程能适当的轮转执行。但,实际无法保证yield()让步目的,因为让步的线程还有可能被调度程序选中运行。
yield()并没有使线程进入到“等待、睡眠、阻塞”状态,在大多数情况下,只是将状态由“运行”转为“可运行”,但有可能没有效果,即又被调度程序选中运行。
join:保证线程执行的顺序,当前线程调用t.join()方法后,其他线程进入等待,直到当前线程执行完,其他线程才可以继续执行。底层是通过wait和notify实现的。
public class ThreadDemo implements Runnable{
public static void main(String[] args){
try {
Thread t1 = new Thread(new ThreadDemo(),"Thread 1");
Thread t2 = new Thread(new ThreadDemo(),"Thread 2");
Thread t3 = new Thread(new ThreadDemo(),"Thread 3");
t1.start();
t1.join();
t2.start();
t2.join();
t3.start();
t3.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
输出结果:
Thread 1
Thread 2
Thread 3
底层代码:
扩展问题:
1.在圆桌上有五个碗和五支筷子,平时一个哲学家进行思考,饥饿时便试图取用其左、右最靠近他的筷子,只有在他拿到两支筷子时才能进餐。进餐完毕,放下筷子又继续思考。
2.多线程交叉输出。
3.ABC三个任务同时进行,如果有一个任务被取消或出现问题,则全部结束,要求高效完成。