什么是进程? 是程序执行的过程 持有资源(内存)和线程 是动态性的 什么是线程? 系统中执行的最小单元 同一个进程有多个线程 线程共享进程的资源 ------------------------------------- 线程的交互 : 互斥 同步 ------------------------------------ 多线程的好处: 1/ 充分利用cpu资源 2/简化编程模型 3/带来良好的用户体验 ========================================= 1/线程初体验: java对多线程的支持: 体现在Thread这个类和Runable接口 ---------------------------------------- public static void main(String[] args) { Thread t = Thread.currentThread(); System.out.println(t.getName()); t.setName("modify"); System.out.println(t.getName()); } ----------------------------------------- ( 一 ) 创建线程 ------------------------------------ 继承Thread 类 --> 重写 run()方法 创建线程对象,调用start启用线程 ------------------------------------ 实现Runnable接口 --> 重写 run()方法 创建线程对象,调用start启用线程 ------------------------------------ 继承: 适用于单继承 编写简单 可以直接操作线程 接口: 避免了单继承的局限性 便于共享资源 推荐使用实现接口类创建接口,很简单 ,java是单根继承,不易于扩展 ---------------------------------------------------------- 启动线程必须调用 start() 方法 主线程和子线程并行交替执行 ====================================================== 观察: 同时开启两条线程 -------------------------------------------- public static void main(String[] args) { Thread thread = new testThread(); Thread thread1 = new testThread(); thread.start(); //线程一启动 thread1.start(); //线程二启动 } ------------------------------------------ 结果: Thread-0--->-56- Thread-0--->-57- Thread-1--->-0- Thread-1--->-1- Thread-1--->-2- ..... 线程一启动,执行一百次,可以发现并未完成一把次的时候线程二启动了 二者交替完成 都完成一百次后停止.... ------------------------------------------------------ 如果是直接调用run方法的结果 ------------------------ thread.run(); thread1.run(); ------------------------- 结果: main--->-98- main--->-99- main--->-0- main--->-1- ............. ------------------------------------------------------ 1/ 将只有主线程一条执行路径 2/ 依次调用了两次run()方法 ========================================================================================= ( 二 ) 线程的状态 创建状态 //启动-----> 就绪状态 new Thread () 并未执行 就绪状态 //获取cpu资源----> 运行状态 调用 .start() 方法 阻塞状态 . sleep()方法 运行状态 死亡状态 ---------------------------------- 线程的调度 线程的api方法 ========= 常用 setPriority() 设置优先级 线程优先级 1~10 , 1 最低 ,10 最高 默认优先级是 5 ; thread.setPriority(Thread.MAX_PRIORITY);//可以调用静态常量 有三个 join() 等待该线程终止后执行 例如 A线程 B线程 本来是交替执行 但B.join(); 则 B执行完毕后 A执行 阻塞主线程,子线程强制执行 yield() 暂停当前的线程 线程的礼让 这是一个静态方法 可以直接调用 使当前线程处于就绪状态并不是阻塞状态 仅仅是给另外一个线程提供机会 在线程实现接口的run方法中 Thread.yield(); 线程礼让 isAlive() 判断是否运行中.. sleep() 让线程休眠 进入阻塞状态 thread.sleep(1000); // 单位 毫秒 ---------------------------------- ( 三 ) 线程的同步 掌握线程的同步 理解线程安全的类型 ----------------------------------------------- 当多个线程操作同一个资源的时候,将会造成数据不安全 ---------------------------- 解决办法: 使用synchronize修饰方法,控制类对成员变量的访问 同步方法 , 给方法加一把锁 只允许一个线程进入方法体 ---------------------------- 线程安全的类型效率低,使用多线程并发共享数据 非线程安全的适用于单线程 ----------------------------------------------- 产生死锁的原因:一是系统提供的资源数量有限,不能满足每个进程的使用;二是多道程序运行时,进程推进顺序不合理。 产生死锁的必要条件是: 1、互斥条件;2、不可剥夺条件(不可抢占);3、部分分配;4、循环等待。 根据产生死锁的四个必要条件,只要使其中之一不能成立,死锁就不会出现。为此,可以采取下列三种预防措施: 1、采用资源静态分配策略,破坏"部分分配"条件; 2、允许进程剥夺使用其他进程占有的资源,从而破坏"不可剥夺"条件; 3、采用资源有序分配法,破坏"环路"条件。 死锁的避免不严格地限制死锁的必要条件的存在,而是系统在系统运行过程中小心地避免死锁的最终发生。 最著名的死锁避免算法是银行家算法。死锁避免算法需要很大的系统开销。 解决死锁的另一条途径是死锁检测方法,这种方法对资源的分配不加限制,即允许死锁的发生。 但系统定时地运行一个"死锁检测"程序,判断系统是否已发生死锁,若检测到死锁发生则设法加以解除。 解除死锁常常采用下面两种方法:1、资源剥夺法;2、撤消进程法
java多线程笔记(一)
最新推荐文章于 2024-07-13 11:25:38 发布