Java线程进程

线程

        1.线程是程序执行中的一个单一控制流程,是程序执行的最小单位,是处理调度分派的基本单位。

        2.一个标准线程由线程ID,当前指令指针,寄存器和堆栈组成

        3.每个线程都有其各自的栈内存 ,堆,多个线程共享一个堆内存

进程

        1.具有一定独立功能的程序在一个数据集上的一次动态执行过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体

多线程

                一个进程中有多个线程,多个线程在表面上看来是同时进行的,但是实际上是多个线程在不断抢夺CPU执行权,交替执行,只不过用时很短,又称分时复用

主线程

        一个进程自带一个线程,称为主线程

子线程

         一个线程除了主线程,其余的都是子线程

前台线程与后台线程

 1.  后台线程会随着主线程(main线程)的结束而结束,但是前台进程则不会(如果main线程先于前台进程结束,前台进程仍然会执行);或者说,只要有一个前台线程未退出,进程就不会终止。;

     2.  默认情况下,程序员创建的线程是用户线程;用setDaemon(true)可以设置线程为后台线程;而用isDaemon( )则可以判断一个线程是前台线程还是后台线程;

     3. jvm的垃圾回收器其实就是一个后台线程;

     4. setDaemon函数必须在start函数之前设定,否则会抛出IllegalThreadStateException异常;

  5.所有的“非后台线程”结束时,程序也就终止了,同时会杀死进程中所有后台线程:main就是一个非后台线程;

    6.后台线程创建的子线程也是后台线程。

守护线程

        守护线程--也称“服务线程”,在没有用户线程可服务时会自动离开。优先级:守护线程的优先级比较低,用于为系统中的其它对象和线程提供服务。

        当JVM中还有线程在执行的时候是不会退出的,意思是非守护线程会“阻止”JVM退出。守护线程不会这样,当JVM中所有非守护线程执行完毕后就会退出执行,并不会考虑是否还有守护线程未执行完毕。JVM中的GC线程就是守护线程,这样设计目的很明确,当你所有的程序都执行完毕了,留着这个GC线程就没有任何意义了

同步

         多个线程在执行时先执行一个再执行另一个,不能同时操作一个数据

异步

        多个线程同时执行,互不干扰

线程与进程

     联系

                        1.一个线程只能属性一个进程,而一个进程可以有多个线程,但至少有一个线程

                        2.资源分配给进程,同一进程的所有线程共享该进程的所有资源

                        3.线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信方法实现同步。线程是指进程内的一个执行单元,也是进程内的可调度实体。

                        4.一个进程至少要保证有一个前台线程存活,否则该进行也将被销毁

                        

     区别

                        1.线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位

                        2.一个线程由一个多个线程组成,线程是一个进程中代码的不同执行路线

                        3.进程之间相互独立,但同一进程下的各个线程之间共享程序的内存空间(包括代码段,数据集,堆等)及一些进程级的资源(如打开文件和信号等)

                        一个进程内的线程在其他进程不可见;

                         4.线程上下文切换比进程上下文切换要快得多。

线程的创建

方案1

         查看源码,可以看到Thread 是个普通类,说明可以直接new出来,但是直接new的话run方法没重写,没啥用,所以需要个继承的

方式1       使用一个类继承于Thread,在该类中重写run方法

               

public class work {
	public static void main(String[] args) {
		Namer namer = new Namer();
		namer.start();//启动线程
		
	}
}

class Namer extends Thread {//创建一个类,继承于Thread

	@Override
	public void run() {//重写run方法
		// TODO Auto-generated method stub
		System.out.println("创建线程");
		super.run();
	}	
}

方式2   使用匿名内部类形式创建线程对象

	Thread thread = new Thread() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				System.out.println("匿名内部类创的");
				super.run();
			}
		};
		
		thread.start();

方案2

使用Runnable

 可以看到传入任务对象

 查看Runnable发现其为接口

将线程任务(Runnable)与线程(Thread)分开

方式1

                创建线程任务对象,在创建线程时传入线程任务对象

                        1.创建一个类,完成Runnable接口

                        2.重写run方法

                       3. 创建该类对象,该类对象就是线程任务对象

                         4.创建线程对象,传入线程任务对象

public class work2 {
	public static void main(String[] args) {
		
		Namber1 namber1 = new Namber1();//创建线程任务
		
		Thread thread = new Thread(namber1);//传入线程
		
		thread.start();//运行
		
		
	}
}

class Namber1 implements Runnable{
	@Override
	public void run() {//实现接口,实现run方法
		// TODO Auto-generated method stub
		System.out.println("创一个线程任务");
	}
}

方式2

                                使用匿名内部类的形式创建线程任务对象

	Thread thread2 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				System.out.println("匿名内部类创的");
				
			}
		});

            thread2.start();

案例:创建三个卖票的,让他们同时卖1000张票

public class Test9 {
	public static void main(String[] args) {
		
		MyPiao myPiao = new MyPiao();
	
		
		Thread thread = new Thread(myPiao,"窗口1");
		Thread thread2 = new Thread(myPiao,"窗口2");
		Thread thread3 = new Thread(myPiao,"窗口3");
		
		thread.start();
		thread2.start();
		thread3.start();
		
	}

}

class MyPiao implements Runnable{
	
	private  int num=1000;

	public MyPiao() {
		super();
		
		// TODO Auto-generated constructor stub
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while (num>0) {
			
			Thread thread = Thread.currentThread();
			String nameString =thread.getName();
			num--;
			System.out.println(nameString+"卖了第"+num+"张");
			
		}
		
	}
}

线程的方法

启动

语法:线程对象.start();

        使用线程对象调用start方法才会开启新的执行路径,如果使用对象调用run相当于调方法,并没有开启新的执行路径

消亡

语法:

                线程对象.stop();可以让线程停止,但是方法已经过时

                线程对象.destroy();是让程序崩溃,该方法也过时了

有斜杠的都过时了,

            不过线程在执行完run方法中的代码之后就会等待系统回收,一般开启线程后我们将不在管理,等待run执行完毕就会自动销毁。

             线程已经启动将不受控制

获取当前线程

语法:Thread 当前线程对象 = Thread.currentThread();

        在那个线程中使用该方法,就是获取那个线程对象

package demo2;

public class work3 {
	public static void main(String[] args) {
		
		Test test = new Test(); 
		
		Thread thread = new Thread(test);
		Thread thread2 = new Thread(test);
		
		System.out.println("thread名字:"+thread.getName());//获取名字
	
		System.out.println("thread2名字:"+thread2.getName());//获取名字
		
		thread.start();
		thread2.start();	
		
	}

}

class Test implements Runnable{
	@Override
	public void run() {
		// TODO Auto-generated method stub
		Thread thread=Thread.currentThread();//运行那个获取那个
		for (int i = 0; i < 10; i++) {
			String string=thread.getName();//获取一下名字
			System.out.println(i+"是"+string+"执行的");//看看是那个线程运行的
			
			
		}
		
	}
	
}

名称

设置名称:

                方法一:

                                在传入时传入线程

                方法二

                                在线程启动前通过setName设置线程名称

                                        线程对象.setName(线程名称);

Thread thread = new Thread(test,"线程1");//传入时传入名称
		Thread thread2 = new Thread(test);
		
		thread2.setName("线程2");//启动前改名

线程有默认名称

获取名称:

                String 线程名称 = 线程对象.getName();

休眠

 作用:线程等待一会

语法:Thread.sleep (休眠时间);

        1,休眠时间单位为毫秒 1000毫秒==1秒

        2,在那个线程中用就是让那个线程休眠

        3,不会释放锁对象

thread睡1s,

		try {
			thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

合并

作用:将多个线程合并为同一个线程

语法:

        线程对象.join();

	try {
							thread.join();
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}

将thread执行完后再执行当前代码,相当于把两者合并了

合并前

 
		Thread thread = new Thread(new Runnable() {		
			@Override
			public void run() {
				// TODO Auto-generated method stub
				for (int i = 0; i < 27; i++) {
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					System.out.println(i);					
				}				
			}
		});
		
		Thread thread2 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				for (int i = 97; i < 123; i++) {						
						try {
							thread.join();
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}			
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
						System.out.println((char)i);
						
					}
				
			}
		});
		
		thread.start();
		thread2.start();

 线程对象.join();

在那个线程调用,就是把  线程对象  名的线程合并过来

 礼让

        作用:放弃本次抢夺的CUP执行权,重新参与抢夺

                语法:Thread.yield();

                注意:在那个线程中使用就是让那个线程放弃本次争夺的CPU权

	Thread.yield();

        放弃本次,下次还会争夺,是个概率问题,有可能这次放弃,下次还是挣到了前面

优先级

作用:增大或减小线程抢夺到CPU执行权的概率

语法: 设置优先级 线程对象.setPriority(优先级);

        获取优先级

                int 线程优先级 = 线程对象.getPriority();

        注意: 1,优先级取值范围1~10,超过范围会报错

                  2,在线程启动前设置

                  3,线程的优先级是5

	thread1.setPriority(9);//设置权限
		
		thread1.start();
		thread2.start();
		int a=thread1.getPriority();//获取权限
		System.out.println("权限"+a);

守护线程

子线程

        前台线程

        守护线程(后台线程)

如果创建一个子线程,默认为前台线程

可以通过: 线程对象.setDaemon(true); 将子线程设置为守护线程

前台线程与守护线程区别:

        当一个进程有前台线程存活时,那么该进程就不会被系统回收,直到当前进程中所有前台程序执行完毕

        如果一个进程所有前台线程执行完毕,还有守护线程正在执行,那么此时不管守护线程是否执行完毕,进程 都将被销毁

        

线程的生命周期:

1.初始状态:NEW

        线程创键后,到启动前

2.就绪状态:Ready

        线程启动后,还没有争夺CPU执行权,准备争夺

3.运行状态:Running

        线程争夺到CUP执行权后,执行run中的代码

        当CPU执行权限时间到了后

                        run方法中代码执行完毕进入终止状态

                        没有执行完,回到就绪状态

4.终止状态:Terminated

                                当线程执行完run方法中的代码后会进入到该状态,等待被系统回收

5.:Timed Waiting 有限期等待

                 如使用线程类调用sleep方法,线程会进入到有限期等待

                 无限期等待 如A线程合并到B线程,A线程就会陷入无限期等

        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值