进程
线程
分时调度
抢占式调度
优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),Java使用的为抢占式调度。
CPU使用抢占式调度模式在多个线程间进行着高速的切换。对于CPU的一个核新而言,某个时刻,只能执行一个线程,而 CPU的在多个线程间切换速度相对我们的感觉要快,看上去就是 在同一时刻运行。 其实,多线程程序并不能提高程序的运行速度,但能够提高程序运行效率,让CPU的 使用率更高。
同步:排队执行 , 效率低,但是安全.
异步:同时执行 , 效率高,但是数据不安全。
并发:指两个或多个事件在同一个时间段内发生。
并行:指两个或多个事件在同一时刻发生(同时发生)。
/** * main方法是运行在主线程里面的,后来开启的线程都是分支线程 * 时间分配是抢占式的 * 每个线程都有自己的栈空间,共用一份堆内存 * @param args */ public static void main(String[] args) { // Thread Java所提供的的用于实现线程的类 // 开始新的线程 MyThread m = new MyThread(); // 开启一个任务 跟后面的for循环里面的任务是并发(同时)执行的 m.start(); for (int i = 0; i < 10; i++) { System.out.println("对影成三人" + i); } }
public static void main(String[] args) { // 实现Runnable // 1. 创建一个任务对象 MyRunnable r = new MyRunnable(); // 2. 创建一个线程,并为其分配一个任务 Thread t = new Thread(r); // 3. 执行这个线程 t.start(); for (int i = 0; i < 10; i++) { System.out.println("可以慰红尘" + i); } }
public class MyRunnable implements Runnable { @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println("我有一壶酒" + i); } } }
public static void main(String[] args) { // 匿名内部类开启线程 new Thread(){ @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println("尽倾江海里" + i); } } }.start(); for (int i = 0; i < 10; i++) { System.out.println("赠饮天下人" + i); } }
/** * 实现Runnable 与 继承Thread相比有如下优势: * 1. 通过创建任务,然后给线程分配的方式来实现的多线程,更适合多个线程同时执行相同任务的情况 * 2. 可以避免继承所带来的的局限性(继承只能单继承,接口可以多实现) * 3. 任务与线程本身是分离的,提高了程序的健壮性。 * 4. 后续学习的线程池技术,接受Runnable类型的任务,不接受Thread类型的线程。 */
public static void main(String[] args) { // 如何获取线程的名称 // 获取当前正在执行的线程对象 System.out.println(Thread.currentThread().getName()); Thread t = new Thread(new MyRunnable()); // 设置名称 t.setName("ha"); t.start(); new Thread(new MyRunnable()).start(); new Thread(new MyRunnable()).start(); } static class MyRunnable implements Runnable { @Override public void run() { // 获取当前线程的名称; System.out.println(Thread.currentThread().getName()); } }
public static void main(String[] args) throws InterruptedException { // 线程的休眠 sleep for (int i = 0; i < 10; i++) { System.out.println(i); // 线程指定时间休眠 Thread.sleep(1000); } // 线程阻塞 所有比较小耗时间的操作(耗时操作) }
public static void main(String[] args) { /** * 线程的中断 * 一个线程是一个独立的执行路径,它是否应该结束,应该尤其自身决定 */ Thread t1 = new Thread(new MyRunnable()); t1.start(); for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName()+":"+i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } // 给线程t1添加中断标记 当主线程运行完之后发现中断标记进入catch块,由程序员决定程序是否终止。也可以不终止,程序会继续运行,不会报错。 t1.interrupt(); } static class MyRunnable implements Runnable { @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName()+":"+i); try { Thread.sleep(1000); } catch (InterruptedException e) { //e.printStackTrace(); //System.out.println("发现了中断标记,但是线程不死亡。"); System.out.println("发现了中断标记,线程死亡。"); // 表示线程死亡 return; } } } }
public static void main(String[] args) { /** * 线程:分为守护线程和用户线程 * 守护线程:守护用户线程的,当最后一个用户线程结束时,所有守护线程自动死亡。 * 用户线程:当一个进程不包含任何的存活的用户线程时,进行结束。 */ Thread t1 = new Thread(new MyRunnable()); // 设置t1为守护线程 t1.setDaemon(true); t1.start(); for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName()+":"+i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } // 给线程t1添加中断标记 当主线程运行完之后发现中断标记进入catch块,由程序员决定程序是否终止。也可以不终止,程序会继续运行,不会报错。 t1.interrupt(); } static class MyRunnable implements Runnable { @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName()+":"+i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); return; } } } }