昨天外出了,没有更,老样子,思考小结。

1.Java为什么要引入线程机制,线程、程序、进程之间的关系是怎样的?

线程可以彼此独立的执行,它是一种实现并发机制的有效手段,可以同时使用多个线程来完成不同的任务,并且一般用户在使用多线程时并不考虑底层处理的细节。

进程(process)是程序的一次执行过程,或是正在运行的一个程序。线程是比进程更小的程序执行单位,一个进程可以启动多个线程同时运行,不同线程之间可以共享相同的内存区域和数据。

2.Java有哪几种创建线程的方式?它们的区别是什么?

有三种方式,如下所示:

(1)继承Thread类:编写简单,如果需要访问当前线程,则无需使用Thread.currentThread()方法,直接使用this即可获得当前线程。但线程类已经继承了Thread类,所以不能再继承其他父类。

(2)实现Runnable接口:避免由于Java单继承带来的局限性。但编程稍微复杂,如果要访问当前线程,则必须使用Thread.currentThread()方法。

(3)使用Callable接口和Future接口创建多线程:避免由于Java单继承带来的局限性,有返回值,可以抛出异常。但编程稍微复杂,如果要访问当前线程,则必须使用Thread.currentThread()方法。

3.什么是线程的生命周期?线程的生命周期中有哪几种状态?

线程从新建到死亡称为线程的生命周期,线程有新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Terminated)五种状态

4.启动一个线程是用run()方法还是start()方法?

启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM调度并执行。这并不意味着线程就会立即运行。run()方法可以产生必须退出的标志来停止一个线程。

5.当一个线程进入一个对象的synchronized方法后,其它线程是否可进入此方法?

不能,一个对象的一个synchronized方法只能由一个线程访问。

6.一个单CPU的机器,如何同时执行多个线程?

从宏观上看,多线程的并发运行时各个线程轮流获得CPU的使用权,分别执行各自的任务。但在运行池中,会有多个处于就绪状态的线程在等待CPU,java虚拟机的一项任务就是负责线程的调度,即按照特定的机制为多个线程分配CPU使用权。调度模型分为分时调度模型和抢占式调度模型两种。前者是让所有线程轮流获得CPU使用权,平均分配每个线程占用CPU的时间片。抢占式调度模型是优先让可运行池中优先级高的线程占用CPU,若运行池中线程优先级相同,则随机选择一个线程使用CPU当它失去CPU使用权时,在随机选取一个线程获取CPU使用权。JAVA默认使用抢占式调度模型。

补充:

  • 线程的优先级:所有处于就绪状态的线程根据优先级存放在可运行池中,优先级低的线程运行机会较少,优先级高的线程运行机会较多,Thread类的setPriority(int newPriority)方法(可设置10种优先级)和getPriority()方法分别用于设置优先级和读取优先级。
  • 线程休眠:Thread类的静态方法sleep(),正在执行的线程调用sleep()方法可以进入阻塞状态,也叫线程休眠,在休眠时间内,即使系统中没有其他可执行的线程,该线程也不会获得执行的机会,当休眠时间结束才可以执行该线程。
  • 线程让步:yield()方法,它与sleep()方法相似,也可以让当前正在执行的线程暂停,但yield()方法不会使线程阻塞,只是将线程转换为就绪状态,也就是让当前线程暂停一下,线程调度器重新调度一下,有可能还会将暂停的程序调度出来继续执行,这就叫做线程让步。
  • 线程插队:join()方法。当某个线程执行中调用其它线程的join()方法时,此线程将被阻塞,直到被join()方法加入的线程执行完为止,称为线程插队。
  • 后台线程(守护线程):线程中有一种后台线程,为其他线程提供服务,JVM的垃圾回收线程就是典型的后台线程。如果所有的前台线程都死亡,后台线程会自动死亡。当整个虚拟机中只剩下后台线程,程序就没有继续运行的必要了,所以虚拟机也就退出了。若将一个线程设置为后台线程,则可以调用Thread类的setDaemon(boolean on)方法,将参数指定为true即可,Thread类还提供了一个isDarmon()方法,用于判断一个线程是否后台线程。

码起来:

1.利用多线程,同时输出10以内的奇数和偶数,以及当前运行的线程名称,输出数字完毕输出

end。

/*** 利用多线程,同时输出10以内的奇数和偶数,以及当前运行的线程名称,输出数字完毕输出end。* 1.synchronized(obj){*     //同步代码块* }* 2.public synchronized void  run() {*  //同步方法* }*/
public class nineA {public static void main(String[] args) {MyRunnable1 myRunnable1 = new MyRunnable1();MyRunnable2 myRunnable2 = new MyRunnable2();new Thread(myRunnable1,"线程偶数:").start();new Thread(myRunnable2,"线程奇数:").start();}
}
//线程1   偶数
class MyRunnable1 implements Runnable{@Overridepublic synchronized void  run() {for (int i = 0; i <= 10; i++) {if (i % 2 == 0){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}//currentThread()方法是在Thread类的静态方法,可以返回当前正在执行的线程对象的引用System.out.println(Thread.currentThread().getName()+":"+i);}}System.out.println(Thread.currentThread().getName()+"end");}
}
//线程2    奇数
class MyRunnable2 implements Runnable{@Overridepublic synchronized void run() {for (int i = 0; i <= 10; i++) {if (i % 2 != 0){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}//currentThread()方法是在Thread类的静态方法,可以返回当前正在执行的线程对象的引用System.out.println(Thread.currentThread().getName()+":"+i);}}System.out.println(Thread.currentThread().getName()+"end");}
}

2.编写一个继承Thread类的方式实现多线程的程序,该类MyThread有两个属性:一个字符串WhoAmI代表线程名,
* 一个整数delay代表该线程随机要休眠的时间。利用有参的构造函数指定线程名称和休眠时间,休眠时间为随机数,
* 线程执行时,会显示线程名,和要休眠时间。最后,在main()方法中创建三个线程对象以展示执行情况。

import java.util.Random;/*** 编写一个继承Thread类的方式实现多线程的程序,该类MyThread有两个属性:一个字符串WhoAmI代表线程名,* 一个整数delay代表该线程随机要休眠的时间。利用有参的构造函数指定线程名称和休眠时间,休眠时间为随机数,* 线程执行时,会显示线程名,和要休眠时间。最后,在main()方法中创建三个线程对象以展示执行情况。*/
public class nineB {public static void main(String[] args) {Random random = new Random();MyThread myThread1 = new MyThread("线程1",((int) (random.nextDouble() * 10000.0)));MyThread myThread2 = new MyThread("线程1",((int) (random.nextDouble() * 10000.0)));MyThread myThread3 = new MyThread("线程1",((int) (random.nextDouble() * 10000.0)));myThread1.start();myThread2.start();myThread3.start();}
}class MyThread extends Thread{private String WhoAmI;private int delay;public MyThread(String whoAmI, int delay) {WhoAmI = whoAmI;this.delay = delay;}@Overridepublic synchronized void run() {try {Thread.sleep(delay);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+":"+delay);}
}

注:死锁问题:
* 不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁。
* 注:在编写代码时要尽量避免死锁,采用专门的算法、原则,尽量减少同步资源的定义。

public class nineC {public static void main(String[] args) {TestDeadLock td1 = new TestDeadLock();TestDeadLock td2 = new TestDeadLock();td1.flag = 1;td2.flag = 0;new Thread(td1).start();new Thread(td2).start();}
}
class TestDeadLock implements Runnable{public int flag = 1;//static静态对象是类的所有对象共享的
//    private static Object o1 = new Object();
//    private static Object o2 = new Object();private Object o1 = new Object();private Object o2 = new Object();@Overridepublic void run() {System.out.println("flag="+flag);if (flag == 1){synchronized (o1){try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}synchronized(o2){System.out.println("1");}}}if (flag == 0){synchronized (o2){try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}synchronized(o1){System.out.println("0");}}}}
}

JAVA程序设计----多线程(上)相关推荐

  1. Java程序设计-书上重点总结

    第一章 Java是一种解释型的程学设计语言,即Java源程序需要通过Java编译器先进行编译生成一种称为字节码的二进制文件,之后用Java解释器来解释执行这种字节码文件. 先通过编译器编译,生成字节码 ...

  2. JAVA程序设计----多线程(下)

    线程通信中的一个经典例子:生产者和消费者问题 接下来是两套代码去实现这个问题.一: package com.nine.nineD;/*** 售货员* wait(),notify(),notifyAll ...

  3. Java程序设计 多线程 基础知识题

    2-1 以下哪个方法用于定义线程的执行体? ( ) (1分) A. start() B. init() C. run() D. ynchronized() 2-2 以下哪个关键字可以用来为对象加互斥锁 ...

  4. 《Java程序设计》实验报告——Java的多线程机制

    浙江理工大学 <Java程序设计>  实验报告  20 19-20 20学年第 1学期      学  院 信息学院 班  级 计算机科学与技术18(3) 姓  名 申屠志刚 学  号 2 ...

  5. 翁凯java程序设计总结(基于C语言基础上)

    ` 翁凯java程序设计总结(基于C语言基础上) 翁恺 Java程序设计B站视频链接 目录 文章目录 翁凯java程序设计总结(基于C语言基础上) 目录 p42逃逸字符 P52用类创造对象 P55对象 ...

  6. java多线程上传文件_Java大文件分片上传/多线程上传

    这里只写后端的代码,基本的思想就是,前端将文件分片,然后每次访问上传接口的时候,向后端传入参数:当前为第几块文件,和分片总数 下面直接贴代码吧,一些难懂的我大部分都加上注释了: 上传文件实体类: 看得 ...

  7. Java程序设计经典习题15道

    Java程序设计总复习题 1.编写一个Java程序在屏幕上输出"你好!".(p13,例1-1) //programme name Helloworld.java public cl ...

  8. 20145209 2016-2017-2 《Java程序设计》第7周学习总结

    20145209 2016-2017-2 <Java程序设计>第7周学习总结 教材学习内容总结 read()每次读入一个字节. eg:short2个字节,2=0x0201,读入后要0x & ...

  9. # 20155337 2016-2017-2 《Java程序设计》第六周学习总结

    20155337 2016-2017-2 <Java程序设计>第六周学习总结 教材学习内容总结 •串流(Stream): 数据有来源及目的地,衔接两者的是串流对象.如果要将数据从来源取出, ...

最新文章

  1. 浏览器传输乱码编解码处理
  2. java 8 永久代_Java8内存结构—永久代(PermGen)和元空间(Metaspace)
  3. 解决Entity Framework中DateTime类型字段异常
  4. 序1--年轻正当时(特权)
  5. Java Decompiler(Java反编译工具)
  6. Spring注解 @Qualifier 说明、用法
  7. python学习笔记简书_Python学习笔记
  8. elk日志系统中elasticsearch 索引read only 解决
  9. Pytorch中的torch.nn.Embedding()
  10. 升级IE11时,失败报错如何解决
  11. 桌面 计算机 win7,计算机动态桌面,教您如何在win7中设置计算机动态桌面
  12. MATLAB制作歌曲
  13. html 转盘素材,jQuery指针不动转盘动的Rotate转盘插件
  14. cents7配置gradle4
  15. WebGL简易教程——目录
  16. 计算机专业用移动硬盘,评测 篇四十三:国产之光,看这款可做移动硬盘又可系统盘的Orico SSD...
  17. JS 大杂烩(持续更新)
  18. Linux驱动框架与杂项字符设备框架介绍
  19. 相声源稿件:对春联国际版
  20. Arcmap高级标注(通过表达式设置颜色/字体/换行等)

热门文章

  1. UVA - 12338 Anti-Rhyme Pairs(后缀数组)
  2. 手机当电脑音响_hifi迷你组合音响怎么样 hifi迷你组合音响优势简介【详解】
  3. LambdaNetworks解读
  4. 启动sqlserver_微软的 SQL Server 你学会了吗?
  5. 树的同构(c语言静态链表实现)
  6. boost使用split分割字符串
  7. cmake Debug模式和Release模式
  8. PyCairo 中的变换
  9. 网页出现不河蟹弹窗?那是被劫持了!
  10. AWS如何迁移实例到另一个区?