线程与进程
**目录: 1、什么是线程、进程、守护线程 2、线程与进程的联系 3、创建线程的方法 4、sleep、yield、join方法、synchronized关键字 **
什么是线程、进程、守护线程
1、线程 线程是进程的一个顺序执行流 2、进程 进程是操作系统运行的一个任务 3、什么是守护线程 守护线程又称为后台线程,守护线程与普通线程在表现上面没有什么区别,只需要通过Thread提供的方法setDeamon(boolean)就可以实现。守护线程的特点是:当进程中只剩下守护线程时,所有守护线程将终止。 4、线程进程举例比较 如下图所示,现要画出5条线,但不是一次画完一条再去画另外一条,而是每条画五分之一,以此往下画。
这相当于5个线程,CPU会让每个线程完成一些,这便体现了多线程。
线程与进程的联系(5个)
1、操作系统创建进程,进程创建线程; 2、线程没有独立的内存,进程有独立的内存; 3、线程共享该进程的所有内存; 4、CPU切换线程的速度比切换进程的速度快; 5、一个进程至少有一个线程;
创建线程的方法(3种)
一、使用Thread创建进程、启动进程
1、创建两个进程,继承Thread并且重写run方法来定义线程要执行的任务
package cn.qiuuuu.thread;
public class TestThread {
public static void main(String[] args) {
Thread bb=new Bbb();
Thread bbb=new Bbbb();
bb.start();
bbb.start();
}
}
class Bbb extends Thread{
public void run(){//重写父类的run方法
for(int i=0;i<100000;i++){
System.out.println("二二二二二二二二二二二二二二");
}
}
}
class Bbbb extends Thread{
public void run(){//重写父类的run方法
for(int i=0;i<100000;i++){
System.out.println("@@@@@@@@@@@@@@@@@@@@@@@");
}
}
}
输出结果: 二二二二二二二二二二二二二二 与 @@@@@@@@@@@@@@@@@@@@@@@ 不是先后顺序显示,而是相见显示,并且无规律!
**注:
- 启动线程要指定start方法,不是直接调用run方法;
- run方法是线程执行的任务;
- 当调用线程的start方法,线程进入runable状态,一旦线程获取到CPU时间,run方法会被自动调用;
- 要继承自父类Thread。**
二、使用Runable创建进程、启动进程
1、创建两个线程,实现Runnable接口并且重写run方法
package cn.qiuuuu.thread;
public class TestRunnable {
public static void main(String[] args){
Runnable r1=new Aaa();
Runnable r2=new Aaaa();
Thread t1=new Thread(r1);
Thread t2=new Thread(r2);
t1.start();
t2.start();
}
}
class Aaaa implements Runnable{
public void run(){//重写接口的run方法
for(int i=0;i<100000;i++){
System.out.println("二二二二二二二二二二二二二二");
}
}
}
class Aaa implements Runnable{
public void run(){//重写接口的run方法
for(int i=0;i<100000;i++){
System.out.println("@@@@@@@@@@@@@@@@@@@@@@@");
}
}
}
**输出结果: 二二二二二二二二二二二二二二 与 @@@@@@@@@@@@@@@@@@@@@@@ 不是先后顺序显示,而是相见显示,并且无规律! 注:
- 启动线程要指定start方法,不是直接调用run方法;
- run方法是线程执行的任务;
- 当调用线程的start方法,线程进入runable状态,一旦线程获取到CPU时间,run方法会被自动调用;
- 要实现接口Runnable。 **
三、使用内部类创建进程
package cn.qiuuuu.thread;
public class Three {
public static void main(String[] args){
new Thread(new Thread(){
public void run(){//重写接口的run方法
for(int i=0;i<100000;i++){
System.out.println("二二二二二二二二二二二二二二");
}
}
}).start();
new Thread(new Runnable(){
public void run(){//重写接口的run方法
for(int i=0;i<100000;i++){
System.out.println("@@@@@@@@@@@@@@@@@@@@@@@");
}
}
}).start();
}
}
sleep、yield、join方法、synchronized关键字
一、线程中的同步操作、异步操作
1、同步操作:有先后顺序的操作,相当于排队,必须前面一个执行完后面才能执行; 2、异步操作:多线程并发的操作,各干各的,不用排队
二、currenthread()获取当前线程的方法
package cn.qiuuuu.thread;
public class ExerciseStartRun_currentThread {
public static void main(String[] args) {
Thread thread=Thread.currentThread();
System.out.println(thread);
}
}
输出结果:
注: Thread[main,5,main]中的main,5,main分别表示:线程名,优先级,线程组
三、setPriority设置线程的优先级
package cn.qiuuuu.thread;
public class ExerciseStartRun_setPriority {
public static void min(String[] args) {
Thread main=new Thread(){
public void run(){
for(int i=0;i<100000;i++){
System.out.println("main");
}
}
};
Thread norm=new Thread(){
public void run(){
for(int i=0;i<100000;i++){
System.out.println("norm");
}
}
};
Thread max=new Thread(){
public void run(){
for(int i=0;i<100000;i++){
System.out.println("max");
}
}
};
main.setPriority(Thread.MIN_PRIORITY);
max.setPriority(Thread.MAX_PRIORITY);
min.start();
norm.start();
max.start();
}
}
输出结果: 运行结果的最后一行一般都是min
二、sleep()方法和join()方法
package cn.qiuuuu.thread;
public class AAAAAAAAAA {
public static boolean isFinish=true;
public static void main(String[] args) {
System.out.println("down:图片开始下载......");
Thread download=new Thread(){
public void run(){
for(int i=0;i<=100;i++){
System.out.println("down:"+i+"%");
try{
Thread.sleep(50);
}catch(InterruptedException e){
e.printStackTrace();
}
}
System.out.println("down:图片下载完毕!");
isFinish=true;
}
};
Thread show=new Thread(){
public void run(){
System.out.println("show:开始显示图片......");
try {
download.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
if(!isFinish){
throw new RuntimeException("图片没有下载完毕");
}
System.out.println("show:图片显示完毕!");
}
};
download.start();
show.start();
}
}
输出结果为: down:图片开始下载...... show:开始显示图片...... down:0% down:1% down:2% down:3% down:4% down:5% down:6% down:7% down:8% down:9% down:10% down:11% down:12% 。。。。。。。。。(此处省略一些百分数) down:90% down:91% down:92% down:93% down:94% down:95% down:96% down:97% down:98% down:99% down:100% down:图片下载完毕! show:图片显示完毕!
注: 1、若不加sleep(50)的话,程序会非常快执行完毕,加了之后会有一些停顿,此处的50表示50毫秒 2、若去掉程序中的:
try {
download.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
,程序的结果会有变化,这样显示图片会在图片没有下载完成之前完成。**此时的结果是:**
down:图片开始下载...... show:开始显示图片...... down:0% show:图片显示完毕! down:1% down:2% down:3% down:4% down:5% down:6% down:7% down:8% down:9% 。。。。。。。。。。。。 down:94% down:95% down:96% down:97% down:98% down:99% down:100% down:图片下载完毕!