进程与线程介绍
进程
线程
区别总结
线程的生命周期
流程如下:
线程的基本状态
线程的状态转换
线程的创建方式
1、继承Thread类创建线程
public class ThreadTest extends Thread {
/**
* 重写run方法,run方法的方法体就是现场执行体
**/
@Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println(getName() + " " + i);
}
}
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + " : " + i);
new ThreadTest().start();
}
}
}
2、通过Runnable接口创建线程类
public class ThreadTest implements Runnable {
@Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
ThreadTest rtt=new ThreadTest();
new Thread(rtt, "新线程1").start();
new Thread(rtt, "新线程2").start();
}
}
}
3、通过Callable和Future创建线程
public class ThreadTest {
public static void main(String[] args) {
ExecutorService executor = Executors.newCachedThreadPool();
try {
System.out.println("主线程正在执行任务");
Thread.sleep(3000);
Task task = new Task();
Future<Integer> result = executor.submit(task);
System.out.println("任务的运行结果:" + result.get());
Thread.sleep(3000);
} catch (InterruptedException | ExecutionException e1) {
e1.printStackTrace();
}
System.out.println("所有的任务执行完毕");
executor.shutdown();
}
}
class Task implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("子线程正在进行计算");
Thread.sleep(3000);
int sum = 0;
for (int i = 0; i < 3; i++) {
sum += i;
}
return sum;
}
}
4、使用线程池创建线程
多线程的优缺点
使用原因
优点
缺点
多线程带来的问题
线程中的sleep和wait
sleep
wait
实例
package thread;
public class MultiThread {
public static void main(String[] args) throws InterruptedException {
new Thread(new Thread1()).start();
Thread.sleep(5000);//主动让出CPU,让CPU去执行其他的线程。在sleep指定的时间后,CPU回到这个线程上继续往下执行
new Thread(new Thread2()).start();
}
}
class Thread1 implements Runnable{
@Override
public void run() {
synchronized (MultiThread.class){
System.out.println("进入线程1");
try{
System.out.println("线程1正在等待");
Thread.sleep(5000);
// MultiThread.class.wait();//wait是指一个已经进入同步锁的线程内(此处指Thread1),让自己暂时让出同步锁,
//以便其他在等待此锁的线程(此处指Thread2)可以得到同步锁并运行。
}catch(Exception e){
System.out.println(e.getMessage());
e.printStackTrace();
}
System.out.println("线程1结束等待,继续执行");
System.out.println("线程1执行结束");
}
}
}
class Thread2 implements Runnable{
@Override
public void run() {
synchronized (MultiThread.class){
System.out.println("进入线程2");
System.out.println("线程2唤醒其他线程");
MultiThread.class.notify();//Thread2调用了notify()方法,但该方法不会释放对象锁,只是告诉调用wait方法的线程可以去
//参与获得锁的竞争了。但不会马上得到锁,因为锁还在别人手里,别人还没有释放。如果notify()
//后面的代码还有很多,需要执行完这些代码才会释放锁。
try {
Thread.sleep(5000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程2继续执行");
System.out.println("线程2执行结束");
}
}
}
线程中的start和run
【面试考点】为什么我们调用 start() 方法时会执行 run() 方法,为什么我们不能直接调用 run() 方法?