Java基础--线程
2018-03-26 15:29
155 查看
一、线程和进程的概念?
1.要想了解多线程,必须先了解线程,要想了解线程,必须先了解进程,因为线程是依赖进程而存在的。
2:什么是进程?
通过任务管理器我们就看到了进程的存在
而通过观察,我们发现只有运行的程序才会有进程
进程:就是正在运行的程序
进程是系统进行资源分配和调用的独立单位,每一个进程都有他自己的内存空间和系统资源。
3:多进程的意义呢?
单进程的计算机只做一件事情,而我们现在的计算机都可以做多件事情
举例:一边玩游戏(游戏进程),一边音乐(音乐进程)。
也就是说现在的计算机都是支持多进程的,可以在一个时间段内执行多个任务。
并且呢,可以提高CPU的使用率
问题:
一边游戏,一边听音乐是同时进行的吗?
不是。因为单CPU在某个时间点上只能做一件事情
而我们在玩游戏,或者听音乐的时候,是CPU在做程序间的高效切换让我们感觉是同时进行。
4:什么是线程?
在同一个进程内又可以执行多个任务,而这每一个任务我就可以看出是一个线程。
线程:是程序的执行单元,执行路径,是程序使用CPU的最基本单位。
单线程:如果程序只有一条执行路径。
多线程:如果程序有多条执行路径
5:多线程的意义?
多线程的存在,不是提高程序的执行速度。其实是为了提高应用程序的使用率。
程序的执行其实都是在抢CPU的资源,CPU的执行权。
多个进程是在抢这个资源,而其中的某一个进程如果执行路径比较多,就会有更高几率抢到CPU的执行权。
我们是不敢保证哪一个线程能够在哪个时刻抢到,所以线程的执行有随机性。
并行和并发的理解?
并行的概念是在某一个时间段内同时运行多个程序,
并发的概念是在某一个时间点上同时运行多个程序
思考题:
* jvm虚拟机的启动是单线程还是多线程的?
* 多线程的。
* 原因是垃圾回收线程也要先启动,否则容易会出现内存溢出。
* 现在的垃圾回收线程加上前面的主线程,最低启动两个线程,所以jvm的启动是多线程的。
6:什么是线程安全和线程非安全?
多个线程访问同一个资源,导致结果和期望值不同,我们就说它是 非线程安全的(线程不安全),反之我们就说它是 线程安全的。
在说start()和run()方法之前我们先说一下run()方法的作用
因为一个类中不是所有的代码都会被线程执行,所以为了区分我们将需要线程执行的代码用run()方法包含起来
所以就有如下所说的run()方法只是一个普通的方法来封装被线程执行的代码
7:面试题start()和run()的区别?
* run()和start()方法的区别?
* run():仅仅是封装被执行的线程代码,直接调用是普通方法
* start():首先启动了线程,然后再由JVM去调用该线程的run()方法。
* MyThread my = new MyThread();
* my.start();
* my.start();
* IllegalThreadStateException:非法的线程状态异常
*
* 因为相当于是my线程被调用了两次,而不是两个线程启动
//正确的是创建两个线程对象
MyThread my1 = new MyThread();
MyThread my2 = new MyThread();
my1.start();
my2.start();
8:什么是守护线程?
在Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程)
用个比较通俗的比如,任何一个守护线程都是整个JVM中所有非守护线程的保姆:
只要当前JVM实例中尚存在任何一个非守护线程没有结束,守护线程就全部工作;只有当最后一个非守护线程结束时,守护线程随着JVM一同结束工作。
Daemon的作用是为其他线程的运行提供便利服务,守护线程最典型的应用就是 GC (垃圾回收器),它就是一个很称职的守护者。
User和Daemon两者几乎没有区别,唯一的不同之处就在于虚拟机的离开:如果 User Thread已经全部退出运行了,只剩下DaemonThread存在了,虚拟机也就退出了。 因为没有了被守护者,Daemon也就没有工作可做了,也就没有继续运行程序的必要了。
/*
* 后台线程:
* public final void setDaemon(boolean on):将该线程标记为守护线程或用户线程
* 当正在运行的线程都是守护线程是,Java虚拟机退出,该方法必须在启动线程前调用
*/
public class ThreadDaemonDemo {
public static void main(String[] args) {
//创建线程对象
ThreadDaemon td1 = new ThreadDaemon();
ThreadDaemon td2 = new ThreadDaemon();
td1.setName("张飞");
td2.setName("关羽");
td1.setDaemon(true);
td2.setDaemon(true);
td1.start();
td2.start();
Thread.currentThread().setName("刘备");
for(int x = 0;x<5;x++){
System.out.println(Thread.currentThread().getName()+":"+x);
}
}
}
9:什么是等待线程终止?
/*
* public final void join():等待线程终止
* 只有引入join()方法的线程执行完之后才能执行其他的线程。
*/
public class ThreadJoinDemo {
public static void main(String[] args) {
//创建线程对象
ThreadJoin tj1 = new ThreadJoin();
ThreadJoin tj2 = new ThreadJoin();
ThreadJoin tj3 = new ThreadJoin();
//设置线程名称
tj1.setName("李渊");
tj2.setName("李世民")
4000
;
tj3.setName("李元霸");
//启动线程
tj1.start();
try {
tj1.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
tj2.start();
tj3.start();
}
}
10:什么是线程的优先级?怎么去设置线程优先级?
/*
* 我们的线程没有设置优先级,肯定有默认优先级。
* 那么,默认优先级是多少呢?
* 如何获取线程对象的优先级?
* public final int getPriority():返回线程对象的优先级
* 如何设置线程对象的优先级呢?
* public final void setPriority(int newPriority()):更改线程的优先级
*
* 注意:
* 线程默认优先级是5
* 线程优先级的范围是:1-10;
* 线程优先级高仅仅是线程获取的CPU时间片的几率高,但是要在此时比较多,或者多次运行的时候才能看到。
*
* IllegalArguementException:非法参数异常
* 抛出的异常表明向方法传递了一个不合法或不正确的参数
*/
public class ThreadPriorityDemo {
public static void main(String[] args) {
ThreadPriority tp1 = new ThreadPriority();
ThreadPriority tp2 = new ThreadPriority();
ThreadPriority tp3 = new ThreadPriority();
tp1.setName("东方不败");
tp2.setName("岳不群");
tp3.setName("林平之");
//默认获取优先级
// System.out.println(tp1.getPriority());
// System.out.println(tp2.getPriority());
// System.out.println(tp3.getPriority());
//设置线程优先级
tp1.setPriority(10);
tp2.setPriority(1);
//启动线程
tp1.start();
tp2.start();
tp3.start();
}
}
11、线程的生命周期?
线程的状态
1、新建状态(New):新创建了一个线程对象。
2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
(一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
(二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
(三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期
12、wait()和sleep()的区别?
wait时会释放锁资源但sleep不会释放锁资源,wait通常和notify以及notifyAll结合使用,需要notify或者notifyAll对其进行唤醒,sleep通常在指定的时间内自动唤醒。
13、实现线程安全的办法?
A:同步代码块
synchronized(对象) {
需要被同步的代码;
}
这里的锁对象可以是任意对象。
B:同步方法
把同步加在方法上。
这里的锁对象是this
C:静态同步方法
把同步加在方法上。
1.要想了解多线程,必须先了解线程,要想了解线程,必须先了解进程,因为线程是依赖进程而存在的。
2:什么是进程?
通过任务管理器我们就看到了进程的存在
而通过观察,我们发现只有运行的程序才会有进程
进程:就是正在运行的程序
进程是系统进行资源分配和调用的独立单位,每一个进程都有他自己的内存空间和系统资源。
3:多进程的意义呢?
单进程的计算机只做一件事情,而我们现在的计算机都可以做多件事情
举例:一边玩游戏(游戏进程),一边音乐(音乐进程)。
也就是说现在的计算机都是支持多进程的,可以在一个时间段内执行多个任务。
并且呢,可以提高CPU的使用率
问题:
一边游戏,一边听音乐是同时进行的吗?
不是。因为单CPU在某个时间点上只能做一件事情
而我们在玩游戏,或者听音乐的时候,是CPU在做程序间的高效切换让我们感觉是同时进行。
4:什么是线程?
在同一个进程内又可以执行多个任务,而这每一个任务我就可以看出是一个线程。
线程:是程序的执行单元,执行路径,是程序使用CPU的最基本单位。
单线程:如果程序只有一条执行路径。
多线程:如果程序有多条执行路径
5:多线程的意义?
多线程的存在,不是提高程序的执行速度。其实是为了提高应用程序的使用率。
程序的执行其实都是在抢CPU的资源,CPU的执行权。
多个进程是在抢这个资源,而其中的某一个进程如果执行路径比较多,就会有更高几率抢到CPU的执行权。
我们是不敢保证哪一个线程能够在哪个时刻抢到,所以线程的执行有随机性。
并行和并发的理解?
并行的概念是在某一个时间段内同时运行多个程序,
并发的概念是在某一个时间点上同时运行多个程序
思考题:
* jvm虚拟机的启动是单线程还是多线程的?
* 多线程的。
* 原因是垃圾回收线程也要先启动,否则容易会出现内存溢出。
* 现在的垃圾回收线程加上前面的主线程,最低启动两个线程,所以jvm的启动是多线程的。
6:什么是线程安全和线程非安全?
多个线程访问同一个资源,导致结果和期望值不同,我们就说它是 非线程安全的(线程不安全),反之我们就说它是 线程安全的。
在说start()和run()方法之前我们先说一下run()方法的作用
因为一个类中不是所有的代码都会被线程执行,所以为了区分我们将需要线程执行的代码用run()方法包含起来
所以就有如下所说的run()方法只是一个普通的方法来封装被线程执行的代码
7:面试题start()和run()的区别?
* run()和start()方法的区别?
* run():仅仅是封装被执行的线程代码,直接调用是普通方法
* start():首先启动了线程,然后再由JVM去调用该线程的run()方法。
* MyThread my = new MyThread();
* my.start();
* my.start();
* IllegalThreadStateException:非法的线程状态异常
*
* 因为相当于是my线程被调用了两次,而不是两个线程启动
//正确的是创建两个线程对象
MyThread my1 = new MyThread();
MyThread my2 = new MyThread();
my1.start();
my2.start();
8:什么是守护线程?
在Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程)
用个比较通俗的比如,任何一个守护线程都是整个JVM中所有非守护线程的保姆:
只要当前JVM实例中尚存在任何一个非守护线程没有结束,守护线程就全部工作;只有当最后一个非守护线程结束时,守护线程随着JVM一同结束工作。
Daemon的作用是为其他线程的运行提供便利服务,守护线程最典型的应用就是 GC (垃圾回收器),它就是一个很称职的守护者。
User和Daemon两者几乎没有区别,唯一的不同之处就在于虚拟机的离开:如果 User Thread已经全部退出运行了,只剩下DaemonThread存在了,虚拟机也就退出了。 因为没有了被守护者,Daemon也就没有工作可做了,也就没有继续运行程序的必要了。
/*
* 后台线程:
* public final void setDaemon(boolean on):将该线程标记为守护线程或用户线程
* 当正在运行的线程都是守护线程是,Java虚拟机退出,该方法必须在启动线程前调用
*/
public class ThreadDaemonDemo {
public static void main(String[] args) {
//创建线程对象
ThreadDaemon td1 = new ThreadDaemon();
ThreadDaemon td2 = new ThreadDaemon();
td1.setName("张飞");
td2.setName("关羽");
td1.setDaemon(true);
td2.setDaemon(true);
td1.start();
td2.start();
Thread.currentThread().setName("刘备");
for(int x = 0;x<5;x++){
System.out.println(Thread.currentThread().getName()+":"+x);
}
}
}
9:什么是等待线程终止?
/*
* public final void join():等待线程终止
* 只有引入join()方法的线程执行完之后才能执行其他的线程。
*/
public class ThreadJoinDemo {
public static void main(String[] args) {
//创建线程对象
ThreadJoin tj1 = new ThreadJoin();
ThreadJoin tj2 = new ThreadJoin();
ThreadJoin tj3 = new ThreadJoin();
//设置线程名称
tj1.setName("李渊");
tj2.setName("李世民")
4000
;
tj3.setName("李元霸");
//启动线程
tj1.start();
try {
tj1.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
tj2.start();
tj3.start();
}
}
10:什么是线程的优先级?怎么去设置线程优先级?
/*
* 我们的线程没有设置优先级,肯定有默认优先级。
* 那么,默认优先级是多少呢?
* 如何获取线程对象的优先级?
* public final int getPriority():返回线程对象的优先级
* 如何设置线程对象的优先级呢?
* public final void setPriority(int newPriority()):更改线程的优先级
*
* 注意:
* 线程默认优先级是5
* 线程优先级的范围是:1-10;
* 线程优先级高仅仅是线程获取的CPU时间片的几率高,但是要在此时比较多,或者多次运行的时候才能看到。
*
* IllegalArguementException:非法参数异常
* 抛出的异常表明向方法传递了一个不合法或不正确的参数
*/
public class ThreadPriorityDemo {
public static void main(String[] args) {
ThreadPriority tp1 = new ThreadPriority();
ThreadPriority tp2 = new ThreadPriority();
ThreadPriority tp3 = new ThreadPriority();
tp1.setName("东方不败");
tp2.setName("岳不群");
tp3.setName("林平之");
//默认获取优先级
// System.out.println(tp1.getPriority());
// System.out.println(tp2.getPriority());
// System.out.println(tp3.getPriority());
//设置线程优先级
tp1.setPriority(10);
tp2.setPriority(1);
//启动线程
tp1.start();
tp2.start();
tp3.start();
}
}
11、线程的生命周期?
线程的状态
1、新建状态(New):新创建了一个线程对象。
2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
(一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
(二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
(三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期
12、wait()和sleep()的区别?
wait时会释放锁资源但sleep不会释放锁资源,wait通常和notify以及notifyAll结合使用,需要notify或者notifyAll对其进行唤醒,sleep通常在指定的时间内自动唤醒。
13、实现线程安全的办法?
A:同步代码块
synchronized(对象) {
需要被同步的代码;
}
这里的锁对象可以是任意对象。
B:同步方法
把同步加在方法上。
这里的锁对象是this
C:静态同步方法
把同步加在方法上。
相关文章推荐
- Java多线程编程基础之线程对象
- 【Dongle】【Java】基础【八】之线程
- java多线程基础(2)-调度方式之暂停当前线程方式1-阻塞
- java基础之线程(重点)
- Java基础复习:线程通信—生产者消费者改进
- 黑马程序员_java基础二(线程和集合)
- JAVA初窥:Thread线程基础
- java线程基础
- Java并发之线程管理(线程基础知识)
- 黑马程序员——Java基础---线程的另一个总结(6)--线程读写锁,缓存小例子
- java基础巩固笔记(5)-多线程之线程并发库
- Java基础-23总结多线程,线程实现Runnable接口,线程名字获取和设置,线程控制,线程安全,同步线程
- java 线程 --- Thread,Runnable,Callable 基础学习
- java+oracle+web(第九天) java 基础课程(三) 多线程同步和死锁(2个线程、四个线程) JDK1.5新方法
- 黑马程序员——java基础:线程
- java基础学习总结——线程(二)
- Java线程和多线程(十二)——线程池基础
- java多线程与高并发库应用(一)线程基础概念
- Java基础巩固之线程学习