在学习操作系统时,我们会学习进程和线程,那么进程和线程又是什么东西呢?
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.
一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
Java程序运行原理
java 命令会启动 java 虚拟机,启动 JVM,等于启动了一个应用程序,也就是启动了一个进程。该进程会自动启动一个 “主线程” ,然后主线程去调用某个类的 main 方法。
所以 main方法运行在主线程中。在此之前的所有程序都是单线程的。
JVM的启动是多线程的吗?
1、Java命令去启动JVM,JVM会启动一个进程,该进程会启动一个主线程。
2、JVM的启动是多线程的,因为它最低有两个线程启动了,主线程和垃圾回收线程。
多线程的实现方案
1、继承Thread类
/** * 该类要重写run()方法,为什么呢? * 不是类中的所有代码都需要被线程执行的。 * 而这个时候,为了区分哪些代码能够被线程执行,java提供了Thread类中的run()用来包含那些被线程执行的代码。 * * @author sun * */ public class MyThread extends Thread { private int i; public MyThread(int i) { super(); this.i = i; } @Override public void run() { System.out.println("i=" + i); } }
/** * 多线程测试 * * @author sun * */ public class ThreadTest { public static void main(String[] args) { MyThread myThread1 = new MyThread(1); MyThread myThread2 = new MyThread(2); MyThread myThread3 = new MyThread(3); MyThread myThread4 = new MyThread(4); MyThread myThread5 = new MyThread(5); myThread1.start(); myThread2.start(); myThread3.start(); myThread4.start(); myThread5.start(); //因为run()方法直接调用其实就相当于普通的方法调用,所以你看到的是单线程的效果 myThread1.run(); } }
由上图的代码,我们也可以看到,线程中的代码也可以用run方法调用。
那么run()和start()的区别在哪呢?
run():仅仅是封装被线程执行的代码,直接调用是普通方法
start():首先启动了线程,然后再由jvm去调用该线程的run()方法。
2、实现Runnable接口
public class MyRunnable implements Runnable { @Override public void run() { System.out.println("运行中!"); } }
/** * * @author sun * */ public class Run { public static void main(String[] args) { Runnable runnable = new MyRunnable(); Thread thread = new Thread(runnable); thread.start(); } }
实现接口Runnable方式的好处
可以避免由于Java单继承带来的局限性。
适合多个相同程序的代码去处理同一个资源的情况,把线程同程序的代码,数据有效分离,较好的体现了面向对象的设计思想。
线程有两种调度模型:
分时调度模型 所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间片
抢占式调度模型 优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的 CPU 时间片相对多一些。
Java使用的是抢占式调度模型。
那么我们已经知道了线程的调度,接下来我们就可以使用如下方法对象线程进行控制
线程休眠 public static void sleep(long millis):在指定的毫秒数内让当前正在执行的线程休眠(暂停执行
线程加入 public final void join():等待该线程终止。
线程礼让 public static void yield(): 暂停当前正在执行的线程对象,并执行其他线程。
中断线程 public final void stop():已过时。 该方法具有固有的不安全性。
public void interrupt():中断线程。
/** * 线程休眠 * * @author sun * */ public class ThreadSleepDemo { public static void main(String[] args) { ThreadSleep ts1 = new ThreadSleep(); ThreadSleep ts2 = new ThreadSleep(); ThreadSleep ts3 = new ThreadSleep(); ts1.setName("sun"); ts2.setName("tin"); ts3.setName("ting"); ts1.start(); ts2.start(); ts3.start(); } } class ThreadSleep extends Thread { @Override public void run() { for (int x = 0; x < 100; x++) { System.out.println(getName() + ":" + x + ",日期:" + new Date()); // 睡眠,设置1秒钟 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
public class ThreadJoinDemo { public static void main(String[] args) { ThreadJoin tj1 = new ThreadJoin(); ThreadJoin tj2 = new ThreadJoin(); ThreadJoin tj3 = new ThreadJoin(); tj1.setName("1"); tj2.setName("2"); tj3.setName("3"); tj1.start(); try { tj1.join(); } catch (InterruptedException e) { e.printStackTrace(); } tj2.start(); tj3.start(); } } class ThreadJoin extends Thread { @Override public void run() { for (int x = 0; x < 100; x++) { System.out.println(getName() + ":" + x); } } }
/** * 暂停当前正在执行的线程对象,并执行其他线程。 * @author sun * */ public class ThreadYieldDemo { public static void main(String[] args) { ThreadYield ty1 = new ThreadYield(); ThreadYield ty2 = new ThreadYield(); ty1.setName("林青霞"); ty2.setName("刘意"); ty1.start(); ty2.start(); } } class ThreadYield extends Thread { @Override public void run() { for (int x = 0; x < 100; x++) { System.out.println(getName() + ":" + x); Thread.yield(); } } }
/* * public final void stop():让线程停止,比较暴力。不推荐使用。 * public void interrupt():中断线程。 把线程的状态终止,并抛出一个InterruptedException。 */ public class ThreadStopDemo { public static void main(String[] args) { ThreadStop ts = new ThreadStop(); ts.start(); try { Thread.sleep(3000); // ts.stop(); ts.interrupt(); } catch (InterruptedException e) { e.printStackTrace(); } } } class ThreadStop extends Thread { @Override public void run() { try { Thread.sleep(10000); } catch (InterruptedException e) { } } }
先说到这吧~