程序,进程,线程相关知识点(1)
定义:
1.进程:在操作系统中运行的程序就是进程,比如游戏,播放器
2。一个进程包含多个线程,比如运行一个播放器,里面有视频播放,有弹幕,并且这些可以同时进行,这些都是一个个线程
3.程序:是指令和数据的有序集合,是一个静态的概念,是程序员写死的,它跑起来就是一个进程
核心概念:
- 线程就是独立的执行路径
- 在程序运行时,即使没有自己创建线程,后台也会有多个线程,如主线程,gc线程
- main()称之为主线程,为系统的入口,用于执行整个程序
- 在一个进程中,如果开辟了多个线程,线程的运行由调度器(cpu)安排,调度器是与操作系统紧密相关的,先后顺序是不能人为的干预的
- 对同一份资源操作时,会存在资源抢夺的问题,需要加入并发控制
- 线程会带来额外的开销,如cpu调度时间,并发控制开销
- 每个线程会在自己的工作内存交互,内存控制不当会造成数据不一致
线程的创建3种方式:
-
继承Thread类:继承Thread类,重写run方法,调用start开启线程 (start方法是线程同时交互进行,run方法只有主线程一条执行路径)
-
实现Runnable接口(推荐使用此方法,因为java单继承的局限性):定义Runnable类实现Runnable接口,实现run()方法,编写线程执行体,创建线程对象,调用start()方法启动线程
-
实现Callable接口:实现Callable接口,需要返回值类型,重写call方法,需要抛出异常,创建目标对象
创建执行服务,提交执行,获取结果,关闭服务
线程的停止:
停止线程
-
不推荐使用jdk提供的stop(),destory()方法(已废弃)
-
推荐线程自己停下来
-
建议使用一个标志位进行终止变量当flag=false,则终止线程运行
例子:
public class TestThreadstop implements Runnable{ //1.设置一个标识符 private boolean flag=true; //2.设置一个公开的方法停止线程,转换标识符 public void stop(){ this.flag=false; } public static void main(String[] args) { // TODO Auto-generated method stub TestThreadstop ttt=new TestThreadstop(); new Thread(ttt).start(); for (int i=0;i<100;i++) { System.out.println("臭小子--->"+i); if(i==70){ ttt.stop();//调用stop方法切换标志位,让线程停止 System.out.println("该线程停止了--->"+i); } } } public void run() { int i=0; while(flag){ System.out.println("run...Thread"+i++); } } }
线程休眠:
-
sleep(时间)指定当前线程阻塞的毫秒数
-
sleep存在异常InterruptedExeception
-
sleep时间达到后线程进入就绪状态
-
sleep可以模拟网络延迟,倒计时等
-
每一个对象都有一个锁,sleep不会释放锁
例子:模拟火车买票时的网络延迟和时间倒计时(可以写在两个线程里,给的例子是把网络延迟和时间倒计时写在一个例子里了)
public class TestSleep implements Runnable{ //票数 int ticketnum=10; public static void main(String[] args) { // TODO Auto-generated method stub TestSleep ts=new TestSleep(); //多个线程操作同一个对象 new Thread(ts,"老张").start(); new Thread(ts,"老李").start(); new Thread(ts,"老刘").start(); } /* (非 Javadoc) * * * @see java.lang.Runnable#run() */ @Override public void run() { while(true){ if(ticketnum<=1){ break; } try { Thread.sleep(1000);//模拟网络延迟,放大问题的发生性,也模拟了时间的倒计时 //创建格式化日期对象 SimpleDateFormat sdf=new SimpleDateFormat("yyy-MM--dd HH:mm:ss"); String format=sdf.format(new Date()); System.out.println(format); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"-->买了第"+ticketnum--+"张票"); } } }
线程礼让:
礼让线程,让当前正在执行的线程暂停,但并不阻塞
将线程从运行状态转为就绪状态
让cpu重新调度,礼让不一定成功!看cpu心情
join:
-
线程强制执行,join合并线程,待此线程执行完成后,在执行其他线程,其他线程阻塞,可以想象成插队
-
使用这个join()方法的线程是主动让别的线程来插队
线程状态:
新生,就绪,运行,阻塞,死亡
线程的优先级
-
线程的优先级用数字表示,范围从1-10
-
Thread.MIN_PRIORITY=1;
-
Thread.MAX_PRIORITY=2;
- Thread.NORM_PRIORITY=5;
使用getPriority()来获取优先级
使用setPriority(int xxx)来改变优先级
守护(daemon)线程
-
线程分为用户线程和守护线程
-
虚拟机必须确保用户线程执行完毕 比如:main()线程
-
虚拟机不用等待守护线程执行完毕 比如:gc线程
守护线程作用:后台记录操作日志,监控内存,垃圾回收等待
里面有setDaemon()方法,类型为boolean类型,true为守护线程,一般默认false用户线程
-
-
-