做外贸密封件的网站,3d建模学什么专业,富阳网站,怎么运营目录: 1.程序2.进程3.线程4.多线程5.自定义线程类 :5.1 继承Thread类5.2 实现Runnable接口 6.多线程的生命周期及状态转换新建状态 (New)就绪状态 (Runnable)运行状态 (Running)阻塞状态 (Blocked)死亡状态 (Terminated) 7.多线程的调度线程的优先级线程的休眠线程的让步yield(… 目录: 1.程序2.进程3.线程4.多线程5.自定义线程类 :5.1 继承Thread类5.2 实现Runnable接口 6.多线程的生命周期及状态转换新建状态 (New)就绪状态 (Runnable)运行状态 (Running)阻塞状态 (Blocked)死亡状态 (Terminated) 7.多线程的调度线程的优先级线程的休眠线程的让步yield() 和 sleep() 的区别 8.多线程同步和通信8.1 多线程的同步8.2 多线程通信 1.程序 程序是对数据描述与操作的。 代码的集合。是应用程序执行的脚本是静态的。 2.进程 在一个操作系统中每个 独立执行的程序 都可以称为一个 进程也就是 “ 正在运行的程序” 强调了 “运行” 的状态。目前大部分计算机安装的都是多任务操作系统即能同时执行多个应用程序。表明看进程是并发执行的实际上这些 进程并不是同时运行的操作系统会为每一个进程分配一段有限的CPU时间CPU在这段时间执行某个进程在下段时间切换到另一个进程。 3.线程 在一个 进程 ( 正在运行的程序 )中可以有 多个 “执行单元” 同时运行它们可以看做 程序执行的一条条路径被称为 “线程”。操作系统中 每一个进程至少存在一个线程。在一个Java程序启动时会产生一个进程该进程默认创建。一个线程在该线程上运行main()方法中的代码。 4.多线程 如果希望 程序中实现“多段程序代码” 交替运行的效果则 需要创建多个线程即 多线程 程序。单线程执行时只有一个路径CPU就一直按按照这个路径执行而多线程有多个路径CPU在多个路径上切换执行。 5.自定义线程类 : 继承Thread类重写run( )方法,在run方法中实现线程中的代码。实现Runnable接口同样要 重写run( )方法 中实现在线程上的代码。 5.1 继承Thread类 继承Thread类创建线程的步骤 为 ①定义类声明继承Thread类。 ②重写Thread的run( )方法run()方法的方法体为线程对应的子任务。 ③创建自定义类的对象调用start( )方法。start( )方法的作用启动线程和调用run( )方法。 由于线程的运行顺序是随机调度的因此会出现不同的结果。 public class Demo {public static void main(String[] args) {//此代码为多线程的程序System.out.println(Demo类的主线程正在运行。);//创建两个线程MyThread myThread1 new MyThread();MyThread myThread2 new MyThread();//启动线程myThread1.start();myThread2.start();System.out.println(Demo的主线程运行结束。);}
}class MyThread extends Thread{Overridepublic void run() {System.out.println(线程Thread.currentThread().getName()的run()方法正在运行。);}
}5.2 实现Runnable接口 通过继承Thread类有一定局限性因为Java只支持单继承一旦继承了某个父类就不能再继承Thread类这时可通过实现Runnable接口来避免这个问题。 Thead类提供了另一个 构造方法 Thread(Runable target)。Runnable接口中只有一个run( )方法因此只需传递一个实现Runnable接口的实例对象就能创建线程。 创建的线程会调用实现Runnable接口中的run( )方法不用调用Thread类的 run( ) 方法。 实现Runnable接口创建线程的步骤 为 ①定义类实现Runnable接口。 ②重写Runnable接口的run( )方法run()方法的方法体为线程对应的子任务。 ③创建自定义类的对象创建Thread类Thread类的构造方法的参数为“自定义的对象”。 ④调用 start( ) 方法开始多线程。 调用start( )方法。start( )方法的作用启动线程和调用run( )方法。 public class Demo2 {public static void main(String[] args) {//此代码为多线程的程序System.out.println(Demo2类的主线程正在运行。);//创建自定义的实现了Runnable接口的类MyThread2 obj new MyThread2();//创建两个线程第二个参数为线程指定的名称Thread t1 new Thread(obj, Thread 1 );Thread t2 new Thread(obj, Thread 2 );//启动线程t1.start();t2.start();System.out.println(Demo2类的主线程运行结束。);}
}class MyThread2 implements Runnable {Overridepublic void run() {System.out.println(线程Thread.currentThread().getName()的run()方法正在运行。);}
}6.多线程的生命周期及状态转换 当Thread对象创建完成时线程的生命周期就开始了。当run()方法中代码正常执行完毕或抛出一个未捕获的异常或错误时线程的生命周期将结束。 线程的生命周期分为五个阶段 ① 新建状态 (New) ② 就绪状态 (Runnable) ③ 运行状态 (Running) ④ 阻塞状态 (Blocked) ⑤ 死亡状态 (Terminated) 新建状态 (New) 创建一个线程对象后该线程对象就处于新建状态。此时不能运行和其他Java对象一样仅为其分配了内存没有任何线程的动态特征。 就绪状态 (Runnable) 当线程对象调用了start( )方法后该线程就进入“就绪状态”此时具备了运行的条件能获得CPU的使用权还需要等待系统的调度。 运行状态 (Running) 就绪状态的线程获得了CPU的使用权开始执行run()方法则线程处于运行状态。当一个线程启动后它不可能一直处于运行状态。 阻塞状态 (Blocked) 一个正在执行的线程在某些特殊情况下如执行耗时的输入/输出操作时会放弃CPU的使用权进入 阻塞状态。只有当引起 阻塞的原因被消除后线程才可以转入就绪状态。 当线程试图获取某个对象的 同步锁 时如果该锁被其他线程所持有时线程会由运行状态转为阻塞状态。 当调用一个阻塞的IO方法要等待这个阻塞的IO方法返回此时 线程会由运行状态转为阻塞状态。 当线程调用了某个对象的wait()方法此时 线程会由运行状态转为阻塞状态 。需要使用notify()方法唤醒该线程。 当线程调用了Thread的sleep(long millis)方法时此时 线程会由运行状态转为阻塞状态。等到休眠时间到了才能进行“就绪状态”。 当线程调用了另一个线程的join()方法时此时 线程会由运行状态转为阻塞状态需要等新加入的线程运行结束后才能结束阻塞。 死亡状态 (Terminated) 当线程的run()方法中代码正常执行完毕或者抛出一个未捕获的异常或者错误时线程进入死亡状态。线程将不在拥有运行的资格也不能再转化到其他状态。 7.多线程的调度 Java虚拟机会按照特定的机制为程序中的 每个线程分配CPU的使用时间这种机制被称为 线程的调度。 线程调度有两种模型 ①分时调度模型 ②抢占式调度模型 分时调度模型所有线程轮流平均分配CPU时间。 抢占式调度模型可运行池中优先级高的线程相同优先级的随机选择一个线程使其占用CPU它失去了使用权之后再随机选择其他线程。 线程的优先级 线程的优先级用1-10之间的整数来表示数字越大优先级越高。可以用Thread类中的 setPriority(int newPriority) 方法进行设置。优先级高的先运行优先级低的后运行。 public class Demo3 {public static void main(String[] args) {MaxP max new MaxP();MinP min new MinP();Thread maxT new Thread(max, 优先级高的程序); //设置了优先级其先执行Thread minT new Thread(min, 优先级低的程序); //其后执行/*** 正常而言优先级高的“线程”先执行优先级低的“线程”后执行。*/maxT.setPriority(10); //设置优先级minT.setPriority(1);maxT.start();minT.start();System.out.println(主线程结束。);}
}class MaxP implements Runnable {public static void main(String[] args) {System.out.println(主线程正在运行。);}Overridepublic void run() {for (int i 0; i 10; i) {System.out.println(Thread.currentThread().getName(): i);}}
}class MinP implements Runnable {Overridepublic void run() {for (int i 0; i 10; i) {System.out.println(Thread.currentThread().getName(): i);}}
}线程的休眠 如果希望人为控制线程使 线程暂停将CPU让给其他线程可以使用sleep(long millis)。 public class Demo4 {public static void main(String[] args) throws InterruptedException {System.out.println(主线程正在运行。);//创建自定义线程对象MyThread mt new MyThread();//创建线程Thread thread new Thread(mt);//启动线程thread.start();for (int i 0; i 10; i) {if (i 5) {//线程休眠后进入阻塞状态休眠结束后重新进入“就绪状态”Thread.sleep(9000); //当i5时Thead.sleep(),该for循环休眠了9秒}System.out.println(主线程输出: i);}System.out.println(主线程运行结束。);}
}class MyThread implements Runnable {Overridepublic void run() {for (int i 0; i 10; i) {System.out.println(MyThread的输出: i);}}
}线程的让步 线程让步 可以通过yield()方法来实现该方法和sleep()方法有点相似都可以让当前 “正在运行” 的线程暂停 。区别在于yield()方法不会阻塞该线程它只是将线程转换为就绪状态重新进入“线程排队”状态。 而sleep() 会让线程进入阻塞状态睡眠结束后该线程才重新进入就绪状态进行“线程排队”。 yield() 和 sleep() 的区别 两个方法功能有点相似 : 都可以让当前“正在运行”的线程暂停最后使线程进入就绪状态后进行“线程排队”。yield() 方法不会阻塞该线程它只是将线程转换为就绪状态重新进入“线程排队”状态。 而 sleep() 会让线程进入阻塞状态睡眠结束后该线程才重新进入就绪状态进行“线程排队”。yield() 告诉操作系统当前线程愿意放弃CPU执行时间片重新进入“就绪状态”进行“线程排队”。但是否会马上执行该“就绪状态”的线程得看操作系统的分配了。sleep() 使得该线程进入休眠状态休眠中为“阻塞状态”。当休眠结束时线程重新进入“就绪状态”进行“线程排队”。 8.多线程同步和通信
8.1 多线程的同步 多线程的并发执行虽然可以提高效率但是当多个线程去访问同一个资源时也会引发一些安全问题。 如线程A读取资源A时线程B正在修改资源A。那么线程A会读取到/该读取到修改之前的资源A还是修改后的资源A呢 可用多线程的同步来避免此类问题 多线程同步的两种常用方法 : ① 同步代码块 synchronized(lock) { 操作共享资源代码块 } ② 同步方法 synchronized 返回值类型 方法名(参数列表) //同步代码块例子
public class Demo5 { public static void main(String[] args) {//自定义线程对象SaleTicket sale new SaleTicket();//创建四个线程模拟四个窗口售票Thread t1 new Thread(sale, 窗口1);Thread t2 new Thread(sale, 窗口2);Thread t3 new Thread(sale, 窗口3);Thread t4 new Thread(sale, 窗口4);t1.start();t2.start();t3.start();t4.start();}}class SaleTicket implements Runnable {int num 50;Overridepublic void run() {while (true) {//创建“同步代码块”synchronized (锁) {if (num 0) {System.out.println(Thread.currentThread().getName() 售出了第 num 号票。);num--;} else {System.out.println(票售完了。);break;}}}}
}public class Demo6 {public static void main(String[] args) {TicketThread2 t new TicketThread2();Thread t1 new Thread(t, 窗口1);Thread t2 new Thread(t, 窗口2);Thread t3 new Thread(t, 窗口3);Thread t4 new Thread(t, 窗口4);t1.start();t2.start();t3.start();t4.start();}
}class TicketThread2 implements Runnable {//总票数int num 50;Overridepublic void run() {while (true) {//调用售票的方法sale();if (num 0) {System.out.println(票卖完了。);break;}}}private synchronized void sale() { //该方法是同步的if (num 0) {System.out.println(Thread.currentThread().getName()售出了num号票。); //获得线程名字等配合其他信息使用num --;}}
}8.2 多线程通信 线程通信 指的是一个线程完成了自己的任务时要通知另外一个线程去完成另外一个任务。 要完成线程之间的通信就需要控制多个线程按照一定的顺序轮流执行。 Object类中提供了wait(), notify() 和notifyALL()方法用于解决线程之间的通信问题。 这三个方法的调用者都应该是同步锁对象否则会抛出IllegalMonitorStateException异常 方法名称功能描述void wait()使当前线程放弃同步锁进入等待直到其他线程进入此同步锁并调用notify()或notifyAll()方法唤醒该线程为止。void notify()唤醒同步锁上等待的第一个调用wait()方法的线程。void notifyAll()唤醒此同步锁上调用wait()方法的所有线程。