(所有异常直接抛出,run方法异常用异常代码块包裹即可)
并发:同一时刻,有多个指令在CPU中交替进行。
并行:同一时刻,有多个指令在CPU中同时进行。
所以,由此可见并发和并行有可能同时进行!
Thread
创建线程的方法也可以查看API文档,文档下载路径在这里、、
APIhttp://xn--https-bl8js66z7n7i//pan.baidu.com/s/1qI7loaFIeR7JdB4mL_I-iw?pwd=1z78%20%20%E6%8F%90%E5%8F%96%E7%A0%81%EF%BC%9A1z78
创建一个类继承Thread类
public class MyThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("xiao---w");
}
}
}
细节都在注释中、、
public class ThreadDemo {
public static void main(String[] args) {
MyThread mt= new MyThread();
//不能直接调用类方法,要用start开启线程
mt.start();
}
}
public class ThreadDemo {
public static void main(String[] args) {
MyThread mt1= new MyThread();
MyThread mt2= new MyThread();
//不能直接调用类方法,要用start开启线程
mt1.start();
mt2.start();
mt1.setName("线程1");
mt2.setName("线程2");
}
}
public class MyThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName()+"xiao---w");
}
}
}
方法同上、、
public class ThreadDemo1 {
public static void main(String[] args) {
MyThread1 mt1= new MyThread1();
Thread thread1 = new Thread(mt1);
Thread thread2 = new Thread(mt1);
//不能直接调用类方法,要用start开启线程
thread1.setName("线程1");
thread2.setName("线程2");
thread1.start();
thread2.start();
}
}
public class MyThread1 implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
Thread thread = Thread.currentThread();
System.out.println(thread.getName()+"xiao---w");
}
}
}
(前两种获取不到多线程的运行结果,第三种可以获取运行结果)
继承Thread类
优点
编程比较简单,可以直接使用Thread类中的方法
缺点
可以扩展性较差,不能再继承其他的类
实现callable接口、实现Runnable接口
优点
扩展性强,实现该接口的同时还可以继承其他的类
缺点
编程相对复杂,不能直接使用Thread类中的方法
上面用到过就不赘述、
注意
当JVM虚拟机启动之后,会自动的启动多条线程其中有一条线程就叫做main线程
他的作用就是去调用main方法,并执行里面的代码
在以前,我们写的所有的代码,其实都是运行在main线程当中
注意
1、哪条线程执行到这个方法,那么这条线程就会在这里停留对应的时间
2、方法的参数:就表示睡眠的时间,单位毫秒1秒= 1000毫秒
3、当时间到了之后,线程会自动的重启,继续执行下面的其他代码
public class ThreadDemo3 {
public static void main(String[] args) {
MyThread3 mt1=new MyThread3("w");
MyThread3 mt2=new MyThread3("c");
//设置线程优先权,数值越大,强占到执行权概率越高
mt1.setPriority(1);
mt2.setPriority(10);
int priority1 = mt1.getPriority();
System.out.println(priority1);
int priority2 = mt1.getPriority();
System.out.println(priority2);
mt1.start();
mt2.start();
}
}
public class ThreadDemo3 {
public static void main(String[] args) {
MyThread3 mt1=new MyThread3("w");
MyThread3 mt2=new MyThread3("c");
//设置线程优先权,数值越大,强占到执行权概率越高
mt1.setPriority(1);
mt2.setPriority(10);
mt1.start();
mt2.start();
}
}
这里我们可以看到w29时,c已经100了
(又称备胎线程,主线程完成后,备胎线程就会陆续结束,不管有没有运行完)
根据代码,mt1和mt2都应该输出1到100,然而mt1被设置成备胎线程之后,在mt2输出完成后,只输出到50就结束了(跟权重无关)
出让CPU的执行权,让所有线程重新抢夺CPU的执行权
让结果尽可能的均匀
mt1.join();
可以让mt1插队先执行完!
—个线程的生命周期通常包括以下几个阶段:
1.创建线程:线程被创建时,它处于新建状态。在这个阶段,线程仅仅被分配了内存空间,但还没有被执行。
⒉.就绪状态:当线程被启动后,它进入就绪状态。在这个阶段,线程已经准备好执行,但是它可能需要在就绪队列中等待,直到操作系统调度它执行。
3.运行状态:当操作系统调度线程执行时,它进入运行状态。在这个阶段,线程正在执行代码,并且占用CPU资源。
4.阻塞状态:当线程需要等待某个条件(例如等待I/o操作完成)时,它进入阻塞状态。在这个阶段,线程不会执行任何代码,并且不会占用CPU资源。
5.终止状态:当线程执行完毕或者被强制终止时,它进入终止状态。在这个阶段,线程已经不再占用任何资源,并且不会再次执行。
这些状态之间可能会相互转换,例如一个正在运行的线程可能会由于等待某个条件而进入阻塞状态,然后当条件满足时又回到就绪状态等待被调度执行。
同步代码块,同步方法,lock锁正在更新 (点个关注实时获取新内容)......
都看到这里了,留个点赞关注再走吧铁子!!!!!!