A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Kevin.Kang 高级黑马   /  2015-8-3 15:31  /  1339 人查看  /  24 人回复  /   2 人收藏 转载请遵从CC协议 禁止商业使用本文

多线程:
    如果程序只有一条执行路径,那么该程序就是单线程程序。
    如果程序有多条执行路径,该程序就是多线程程序。

进程:
    正在运行的程序就是进程
    进程是系统进行资源分配和调用的独立单位,每一个进程都有它自己的内存空间和系统资源。

多进程意义:
    单进程的计算机同一时间只能做一件事情,现在的计算机可以做很多事情。
    也就是说现在的计算机支持多进程,可以在同一时间段内执行多个任务。并且提高CPU的使用率。

    一边打游戏,一边听音乐,不是同时进行的,单CPU在某一时间点上只能做一件事。
    CPU在做程序间的高效切换让我们感觉打游戏和听音乐是同时进行的。

    一个程序只有一条执行路径,称为单线程程序。
    一个程序有多条执行路径,称为多线程程序。

什么是线程:
    同一进程内又可以执行多个任务,而这每一个任务就可以看成一个线程。
    线程是程序的执行单元,执行路径。是程序使用CPU的最基本单位。

多线程的意义:
    多线程的存在,不是为了提高程序的执行速读,是为了提高应用程序的使用率。
    程序的执行其实就是在抢CPU的资源,CPU的执行权。
    多个进程在抢资源的时候,其中某一个进行的执行路径比较多,就会有更高的几率抢到CPU的执行权。
    但是不能保证的是哪一个线程在哪个时刻抢到执行权,所以线程的执行有随机性。

并发和并行的区别:
    并发是逻辑上同时发生,指在某一时间内同时运行多个程序。
    并发是物理上同时发生,指在某一时间点同时运行多个程序。

JAVA程序运行原理:
    java命令会启动java虚拟机,启动JVM就等于启动了一个应用程序,也就是一个进程,
    这个进行自动启动一个“主进程”,然后主进程调用某个类的main方法。所以main方法运行在主线程中。

JAVA虚拟机的启动是多线程的,除了主线程,至少还需要垃圾回收线程,否则内存很快就会溢出。

24 个回复

正序浏览
线程感觉学的时候比较简单,真正到用的时候实现起来会复杂点,因为真正需要掌握的方法并不多
回复 使用道具 举报
学习了  看的好仔细
回复 使用道具 举报

这个m1.join()后,在你写的这段程序中是main线程需要等待m1执行完再执行,对m2 m3没影响
回复 使用道具 举报
小康!!! 收藏了  嘿嘿
回复 使用道具 举报
感谢楼主分享!
回复 使用道具 举报
更加深刻懂了多线程。
回复 使用道具 举报
。。。。。。。。。。。。。。。。。。
回复 使用道具 举报
方式3:实现Callable接口,需要和线程池结合使用
实现类:
  1. package com.kxg_06;
  2. import java.util.concurrent.Callable;

  3. /*
  4. * Callable<V>:带泛型的接口
  5. *                 接口中只有一个方法:V call()
  6. *                 接口中的泛型是call()方法的返回值类型
  7. *
  8. */
  9. public class MyCallable implements Callable {

  10.         @Override
  11.         public Object call() throws Exception {
  12.                 for (int i = 0; i < 100; i++) {
  13.                         System.out.println(Thread.currentThread().getName() + ":" + i);
  14.                 }
  15.                 return null;
  16.         }
  17. }
复制代码
测试类:
  1. package com.kxg_06;

  2. import java.util.concurrent.ExecutorService;
  3. import java.util.concurrent.Executors;

  4. public class MyCallableDemo {
  5.         public static void main(String[] args) {
  6.                 // 创建线程池对象
  7.                 ExecutorService pool = Executors.newFixedThreadPool(2);

  8.                 // 添加Callable实现类
  9.                 pool.submit(new MyCallable());
  10.                 pool.submit(new MyCallable());

  11.                 // 结束线程池
  12.                 pool.shutdown();
  13.         }
  14. }
复制代码



回复 使用道具 举报
线程的状态转换图及常见执行情况:

线程的状态转换图及常见执行情况.jpg (1.93 MB, 下载次数: 26)

线程的状态转换图及常见执行情况.jpg
回复 使用道具 举报
{:2_31:}!!!!!!!!!!!!!!!!!!!!!
回复 使用道具 举报
判断线程是否有问题的标准
    1.是否是多线程环境
    2.是否有共享数据
    3.是否有多条语句操作共享数据

回复 使用道具 举报
方式2好处:
1.可以避免由于java单继承带来的局限性
2.适合多个相同程序的代码去处理同一个资源的情况,
把线程和程序的代码,数据有效分离,较好的体现了面向对象的设计思想。

回复 使用道具 举报
方式2:通过实现Runnable接口的实现类
  1. package com.kxg_07;
  2. /*
  3. * 实现Runnable接口
  4. */
  5. public class MyRunnable implements Runnable {

  6.         @Override
  7.         public void run() {
  8.                 for (int i = 0; i < 100; i++) {
  9.                         System.out.println(Thread.currentThread().getName() + ":" + i);
  10.                 }
  11.         }
  12. }
复制代码
  1. package com.kxg_07;

  2. /*
  3. * 实现Runnable接口
  4. * 步骤:
  5. *                 1.自定义类MyRunnable实现Runnabe接口
  6. *                 3.创建MyRunnable对象
  7. *                 4.创建Thread类的对象,把MyRunnable对象作为构造参数传递
  8. */
  9. public class RunnableDemo {
  10.         public static void main(String[] args) {
  11.                 // 创建对象
  12.                 MyRunnable mr = new MyRunnable();

  13.                 // 设置线程
  14.                 Thread t1 = new Thread(mr);
  15.                 Thread t2 = new Thread(mr);

  16.                 // 设置线程名称
  17.                 t1.setName("深圳");
  18.                 t2.setName("上海");

  19.                 // 启动线程
  20.                 t1.start();
  21.                 t2.start();
  22.         }
  23. }
复制代码



回复 使用道具 举报
线程生命周期:

线程生命周期图解.png (1.93 MB, 下载次数: 22)

线程生命周期图解.png
回复 使用道具 举报
中断线程:
  1. package com.kxg_06;

  2. /*
  3. * 中断线程:
  4. *                 public void interrupt()
  5. */

  6. public class TreadDemo {
  7.         public static void main(String[] args) {
  8.                 // 创建线程
  9.                 MyThread m1 = new MyThread();
  10.                 MyThread m2 = new MyThread();

  11.                 // 设置线程名称
  12.                 m1.setName("深圳");
  13.                 m2.setName("上海");

  14.                 // 中断线程,后面的线程还可以继续运行
  15.                 m1.interrupt();
  16.                 // 启动线程
  17.                 m2.start();
  18.         }
  19. }
复制代码



回复 使用道具 举报
本帖最后由 Kevin.Kang 于 2015-8-3 18:22 编辑

守护线程:
  1. package com.kxg_06;

  2. /*
  3. * public final void setDaemon(boolean on):将该线程标记为守护线程或用户线程。
  4. *                 当正在运行的线程都是守护线程时,Java 虚拟机退出。该方法必须在启动线程前调用。
  5. */

  6. public class TreadDemo {
  7.         public static void main(String[] args) {
  8.                 // 创建线程
  9.                 MyThread m1 = new MyThread();
  10.                 MyThread m2 = new MyThread();

  11.                 // 设置守护线程
  12.                 m1.setDaemon(true);
  13.                 m2.setDaemon(true);
  14.                 // 设置线程名称
  15.                 m1.setName("深圳");
  16.                 m2.setName("上海");

  17.                 // 启动线程
  18.                 m1.start();
  19.                 m2.start();

  20.                 // 设置当前运行线程名称
  21.                 Thread.currentThread().setName("北京");
  22.                 for (int i = 0; i < 10; i++) {
  23.                         // Thread.currentThread().getName():当前执行的线程的名称
  24.                         System.out.println(Thread.currentThread().getName() + ":" + i);
  25.                 }
  26.         }
  27. }
复制代码
m1,m2设置称为守护线程,当前运行主线程结束的时候,m1,m2都会随之结束。但已经抢到了执行权,不可能立马结束,会稍微运行一下。


回复 使用道具 举报
礼让线程:执行效果就是两个线程你一次,我一次的执行
  1. package com.kxg_05;
  2. public class MyThread extends Thread {
  3.         public void run() {
  4.                 for (int i = 0; i < 100; i++) {
  5.                         System.out.println(getName() + ":" + i);

  6.                         // public static void yield():暂停当前正在执行的线程对象,并执行其他线程。也称为礼让线程
  7.                         Thread.yield();
  8.                 }
  9.         }
  10. }
复制代码



回复 使用道具 举报
好东西,留着看
回复 使用道具 举报
加入线程:
  1. package com.kxg_04;

  2. /*
  3. * public final void join():等待该线程终止。
  4. *                 别的线程需要等待这个加入的线程执行结束才能执行。
  5. */
  6. public class TreadDemo {
  7.         public static void main(String[] args) {
  8.                 // 创建线程
  9.                 MyThread m1 = new MyThread();
  10.                 MyThread m2 = new MyThread();
  11.                 MyThread m3 = new MyThread();

  12.                 // 设置线程名称
  13.                 m1.setName("北京");
  14.                 m2.setName("上海");
  15.                 m3.setName("广州");

  16.                 // 启动线程
  17.                 m1.start();
  18.                 // 加入线程
  19.                 try {
  20.                         m1.join();
  21.                 } catch (InterruptedException e) {
  22.                         e.printStackTrace();
  23.                 }
  24.                 m2.start();
  25.                 m3.start();
  26.         }
  27. }
复制代码



回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马