线程和进程区别
什么是进程,程序运行的时候会对应一个进程,进程就是处于运行的程序,进程具有并发性。什么是线程,线程是轻量级进程,是进程的执行单元。
并发性:多个进程再单个处理器上并发执行,多个进程之间不会互相影响
并行性:在同一时刻,有多条指令在多个处理器上同时执行
线程的三种实现方法
public class test {
public static void main(String[] args) {
MyThread1 t1 = new MyThread1();
Thread t2 = new Thread(new MyThread2(),"Runnable接口实现的线程");
FutureTask<Integer> task = new FutureTask<>(new MyThread3());
Thread t3 = new Thread(task,"Callable接口实现的线程");
t1.start();
t2.start();
t3.start();
System.out.println("Callable接口实现的线程的返回值是"+task.get());
}
}
class MyThread1 extends Thread{
//继承Thread方法实现
@Override
public void run() {
this.setName("继承实现的线程");
for (int i = 0; i < 100; i++) {
System.out.println(this.getName()+"的循环变量i的值为"+i);
}
}
}
class MyThread2 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+"的循环变量i的值为"+i);
}
}
}
class MyThread3 implements Callable<Integer>{
@Override
public Integer call() {
int i = 0;
for (; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+"的循环变量i的值为"+i);
}
return i;
}
}
输出
继承实现的线程的循环变量i的值为0
Callable接口实现的线程的循环变量i的值为0
Runnable接口实现的线程的循环变量i的值为0
Callable接口实现的线程的循环变量i的值为1
继承实现的线程的循环变量i的值为1
...
Callable接口实现的线程的返回值是100
- Callable接口是Runnable接口的增强版,Callable接口提供call()方法作为线程执行体,call()方法可以有返回值,也可以抛出异常
- java程序运行时
main()
方法的方法体会执行默认的主线程
线程的生命周期
新建:当程序使用new关键字创建一个线程之后
就绪:当线程对象调用start()方法之后
运行:开始执行run()方法的线程执行体
阻塞:当遇到会使程序停止的条件,如调用sleep()方法、调用阻塞式IO方法、线程在等待某个通知(notify)、调用suspend()方法(不推荐)
死亡:线程正常结束、抛出异常、stop()(不推荐)死亡的线程无法再次调用start()会引发IllegalThreadStateException异常
线程控制
- join:当在某个程序执行流中调用其他线程的join()方法时,调用线程将被阻塞,直到被join()方法加入的join线程执行完为止
public class test {
public static void main(String[] args) throws InterruptedException {
MyThread1 t1 = new MyThread1("新线程");
MyThread1 t2 = new MyThread1("join线程");
t1.start();
for (int i = 0; i < 100; i++) {
if (i == 20) {
t2.start();
t2.join();
}
System.out.println(Thread.currentThread().getName()+"的循环变量i值为"+i);
}
}
}
class MyThread1 extends Thread{
MyThread1 (String name) {
super(name);
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(this.getName()+"的循环变量i的值为"+i);
}
}
}
输出
新线程的循环变量i的值为0
main的循环变量i值为0
....新线程核main交叉循环...
新线程的循环变量i的值为29
join线程的循环变量i的值为0
...当main到19停止,join和新线程交叉循环...
join线程的循环变量i的值为98
join线程的循环变量i的值为99
main的循环变量i值为20
main的循环变量i值为21
...当join线程结束后,main线程继续...
- sleep:线程睡眠
- yield:线程让步
俩者区别:sleep()
暂停后会不管其他线程优先级给其他线程执行机会,但yield()
只会给相同或更高的线程机会
sleep()
后线程变为阻塞状态,yield()
后线程会变成就绪状态
yield()
没有声明抛出任何异常
sleep()
比yield()
有更好的可移植性,通常不建议使用yield()
方法控制并发线程 - 设置线程优先级:高优先级有较多的执行机会,通过
setPriority()
方法设置
网友评论