进程和线程
进程是操作系统分配资源的基础单位;它是一个程序运行一次的从开始到结束的过程集合;而线程是进程的子类,为解决cpu使用率 而提出的进程可以分为多个线程;(基础知识 操作系统 参考资料:现代操作系统)
java线程概念
线程状态: 初始化 就绪状态 运行状态 堵塞状态 完成状态
初始化状态就是我们的线程对象初始化 资源分配完毕;
就绪状态是线程可运行 等待os选中分配cpu时间片段;
运行状态是获得cpu时间片段 执行线程;
堵塞状态 是因为同步锁 sleep 或者其他需等待事务导致的线程等待;
完成状态是 线程运行结束;
java内存模型
当一个运行main方法jvm会分配一个进程内存给运行的程序,当我们运行一个线程的时候 jvm会在这个进程的内存主攻划分一片给线程 用来记录线程中间量 和状态量;
当线程开始从初始态转化为就绪态的时候就是为线程分配线程存储空间;
当线程由就绪态转化为运行态的时候 线程读取进程种的信息存储到线程存储空间然后进行运算;
当线程堵塞挂起的时候 所有存储在线程存储空间的数据不回写进程存储空间;
当线程再次转化为就绪状态或者完成状态时 线程存储空间的信息回写进程存储空间;
(以上只是个人理解 未加证实,因为我还没看官方文档这一块的内容,使用时还请慎重)
java线程的实现和启动
java线程实现有两种方式 实现runnable接口和继承Runnable的实现类Thread类;
1,实现Runnable接口
package top;public class Thread2 implements Runnable { private static int count = 10000; private String tname; public Thread2(String tname) { this.tname = tname; } public String getTname() { return tname; } public void setTname(String tname) { this.tname = tname; } public void run() { for (int i = count; count > 0; count--) { System.out.println(getTname() + ":" + count); try { Thread.currentThread().sleep(10l); } catch (InterruptedException e) { e.printStackTrace(); } } } /** * 主方法 开启一个进程 * * @param args */ public static void main(String[] args) { // 在进程中开启多个线程 Thread t1 = new Thread(new Thread2("线程1")); t1.start(); Thread t2 = new Thread(new Thread2("线程2")); t2.start(); Thread t3 = new Thread(new Thread2("线程3")); t3.start(); Thread t4 = new Thread(new Thread2("线程4")); t4.start(); }}
2,继承Thread来实现
package top;/** * 通过集成Thread类实现线程 * * @author ZGang * */public class Thread1 extends Thread { private static int count = 10000; private String tname; public Thread1(String name) { this.tname = name; } /** * run方法 来实现我们的多线程需要做的计算 */ @Override public void run() { for (int i = count; count > 0; count--) { System.out.println(getTname() + ":" + count); try { this.sleep(10l); } catch (InterruptedException e) { e.printStackTrace(); } } } public String getTname() { return tname; } public void setTname(String tname) { this.tname = tname; } /** * 主方法 开启一个进程 * * @param args */ public static void main(String[] args) { // 在进程中开启多个线程 Thread1 t1 = new Thread1("线程1"); t1.start(); Thread1 t2 = new Thread1("线程2"); t2.start(); Thread1 t3 = new Thread1("线程3"); t3.start(); Thread1 t4 = new Thread1("线程4"); t4.start(); }}
线程锁
为什么需要线程锁呢?在多线程的状态下,线程虽然都有自己的存储空间 但是最后的状态都是需要回写到进程的存储空间中的;但是线程可能会堵塞 在一个线程堵塞的时候是不回写状态到进程存储空间的,如果在这堵塞的过程中第二个线程需要对状态进行操作,那么第二个线程还是读取第一个线程未做回写的状态; 在这种情况下,当两个线程都运行完毕了 势必会导致状态值不正确!
因此在此时引入线程锁的概念,当一个线程启动 不想让别的线程误读次此状态,那么在读取状态到此线程的存储空间的时候,还会告诉进程存储空间 这个状态是我拿去用了,如果别人要用;等我送回来;
多线程就像借书这个流程 图书馆里面的一本书就是程序的状态,我借了之后;告诉图书管理员;在我刚拿到书没多久 第二个线程开始运作,第二个人来借同一本书 然后管理员说已经借走了,你需要等候他送回来;