06 多线程
2016-01-22 19:22
316 查看
06 多线程
###06.01_什么是线程
* 线程是程序执行的一条路径, 一个进程中可以包含多条线程
* 多线程并发执行可以提高程序的效率, 可以同时完成多项工作
###06.02_多线程并行和并发的区别
* 并行就是两个任务同时运行,就是甲任务进行的同时,乙任务也在进行。(需要多核CPU)
* 并发是指两个任务都请求运行,而处理器只能按受一个任务,就把这两个任务安排轮流进行,由于时间间隔较短,使人感觉两个任务都在运行。
###06.03_多线程(多线程程序实现的方式1)
* 1.继承Thread
* 定义类继承Thread
* 重写run方法,把新线程要做的事写在run方法中
* 创建线程对象
* 开启新线程, 内部会自动执行run方法
public class Demo2_Thread {
public static void main(String[] args) {
MyThread mt = new MyThread();//4,创建自定义类的对象
mt.start();
//5,开启线程
for(int i = 0; i < 3000; i++) {
System.out.println("bb");
}
}
}
class MyThread extends Thread {//1,定义类继承Thread
public void run() {//2,重写run方法
for(int i = 0; i < 3000; i++) {//3,将要执行的代码,写在run方法中
System.out.println("aaaaaaaaaaaaaaaaaaaaaaaaaaaa");
}
}
}
###06.04_多线程(多线程程序实现的方式2)
* 2.实现Runnable
* 定义类实现Runnable接口
* 实现run方法,把新线程要做的事写在run方法中
* 创建自定义的Runnable的子类对象
* 创建Thread对象, 传入Runnable
* 调用start()开启新线程, 内部会自动调用Runnable的run()方法
public class Demo3_Runnable {
public static void main(String[] args) {
MyRunnable mr = new MyRunnable();//4,创建自定义类对象
//Runnable target = new MyRunnable();
Thread t = new Thread(mr);//5,将其当作参数传递给Thread的构造函数
t.start();
//6,开启线程
for(int i = 0; i < 3000; i++) {
System.out.println("bb");
}
}
}
class MyRunnable implements Runnable {//1,自定义类实现Runnable接口
@Override
public void run() {//2,重写接口Runnable的run方法
for(int i = 0; i < 3000; i++) {//3,将要执行的代码,写在run方法中
System.out.println("aaaaaaaaaaaa");
}
}
}
###06.05_多线程(两种方式的区别)
* 继承Thread
* 好处是:可以直接使用Thread类中的方法,代码简单
* 弊端是:如果已经有了父类,就不能用这种方法
* 实现Runnable接口
* 好处是:即使自己定义的线程类有了父类也没关系,因为有了父类也可以实现接口,而且接口是可以多实现的
* 弊端是:不能直接使用Thread中的方法需要先获取到线程对象后,才能得到Thread的方法,代码复杂
###06.06_多线程(匿名内部类实现线程的两种方式)
* 继承Thread类
new Thread() {//1,new 类(){}继承这个类
public void run() {//2,重写run方法
for(int i = 0; i < 3000; i++) {//3,将要执行的代码,写在run方法中
System.out.println("aaaaaaaaaaaaaaaaaaaaaaaaaaaa");
}
}
}.start();
* 实现Runnable接口
new Thread( new Runnable(){//1,new 接口(){}实现这个接口
public void run() {//2,重写run方法
for(int i = 0; i < 3000; i++) {//3,将要执行的代码,写在run方法中
System.out.println("bb");
}
}
} ).start();
###06.07_多线程(休眠线程)
* Thread.sleep(毫秒,纳秒), 控制当前线程休眠若干毫秒 1秒= 1000毫秒 1秒 = 1000 * 1000 * 1000纳秒 1000000000
* 会有InterruptedException异常
###06.08_多线程(守护线程)
* setDaemon(), 设置一个线程为守护线程, 该线程不会单独执行, 当其他非守护线程都执行结束后, 自动退出
###06.09_多线程(加入线程)
* join(), 使当前线程暂停, 等待指定的线程执行结束后, 当前线程再继续
* join(int), 可以指定等待时间毫秒值,之后再继续执行交替执行
###06.10_多线程(设置线程的优先级)
* setPriority()设置线程的优先级
//t1.setPriority(1);
//传数字和常量都可以 ,1最小,5默认,10最大
//t2.setPriority(10);
t1.setPriority(Thread.MAX_PRIORITY);
t2.setPriority(Thread.MIN_PRIORITY);
###06.11_多线程(同步代码块)
* 1.什么情况下需要同步
* 当多线程并发, 有多段代码同时执行时, 我们希望某一段代码执行的过程中CPU不要切换到其他线程工作. 这时就需要同步.
* 如果两段代码是同步的, 那么同一时间只能执行一段, 在一段代码没执行结束之前, 不会执行另外一段代码.
* 2.同步代码块
* 使用synchronized关键字加上一个锁对象来定义一段代码, 这就叫同步代码块
* 多个同步代码块如果使用相同的锁对象, 那么他们就是同步的
public class Demo_同步代码块 {
public static void main(String[] args) {
final Print p = new Print();
//用final修饰
new Thread(){
public void run(){
for (int i = 0; i < 500; i++) {
p.print1();
}
}
}.start();
new Thread(){
public void run(){
for (int i = 0; i < 500; i++) {
p.print2();
}
}
}.start();
}
}
class Print{
Deemmoo d = new Deemmoo();
public void print1(){
synchronized(d){ //锁对象可以是任意对象,但是被锁的代码需要保证是同一把锁,所以不能用匿名对象
System.out.print("黑");
System.out.print("马");
System.out.print("程");
System.out.print("序");
System.out.print("员");
System.out.print("\r\n");
}
}
public void print2(){
synchronized(d){
System.out.print("你");
System.out.print("真");
System.out.print("的");
System.out.print("很");
System.out.print("美");
System.out.print("\r\n");
}
}
}
class Deemmoo{
}
###06.12_多线程(同步方法)
* 使用synchronized关键字修饰一个方法, 该方法中所有的代码都是同步的 //同步方法只需要在方法上加synchronized关键字即可
###06.13_多线程(线程安全问题)
* 多线程并发操作同一数据时, 就有可能出现线程安全问题
* 使用同步技术可以解决这种问题, 把操作数据的代码进行同步, 不要多个线程一起操作
###06.14_多线程(单例设计模式)
* 单例设计模式:保证类在内存中只有一个对象。
* 如何保证类在内存中只有一个对象呢?
* (1)控制类的创建,不让其他类来创建本类的对象。private
* (2)在本类中定义一个本类的对象。Singleton s;
* (3)提供公共的访问方式。 public static Singleton getInstance(){return s}
* 饿汉式和懒汉式的区别
* 1,饿汉式是空间换时间,懒汉式是时间换空间
* 2,在多线程访问时,饿汉式不会创建多个对象,而懒汉式有可能会创建多个对象
* 单例写法两种:
* (1)饿汉式 开发用这种方式。
//饿汉式
class Singleton {
//1,私有构造函数
private Singleton(){}
//2,创建本类对象
private static Singleton s = new Singleton();
//3,对外提供公共的访问方法
public static Singleton getInstance() {
return s;
}
public static void print() {
System.out.println("11111111111");
}
}
* (2)懒汉式 面试写这种方式。多线程的问题?
//懒汉式, 单例的延迟加载模式
class Singleton {
//1,私有构造函数
private Singleton(){}
//2,声明一个本类的引用
private static Singleton s;
//3,对外提供公共的访问方法
public static Singleton getInstance() {
if(s == null)
//线程1,线程2 当时多线程的时候可能出现多个对象
s = new Singleton();
return s;
}
public static void print() {
System.out.println("11111111111");
}
}
* (3)第三种格式
class Singleton {
private Singleton() {}
public static final Singleton s = new Singleton(); //final是最终的意思,被final修饰的变量不可以被更改
}
###06.15_多线程(线程间的通信注意的问题)
* 1,在同步代码块中,用哪个对象锁,就用哪个对象调用wait方法
* 2,为什么wait方法和notify方法定义在Object类中? 因为锁对象可以是任意对象,Object是所有的类的基类,所以wait方法和notify方法需要定义在Object这个类中
* 3,sleep方法和wait方法的区别?
* a,sleep方法必须传入参数,参数就是时间,时间到了自动醒来
wait方法可以传入参数也可以不传入参数,传入参数就是在参数的时间结束后等待,不传入参数就是直接等待
* b,sleep方法在同步函数或同步代码块中,不释放锁,睡着了也抱着锁睡,一直占用cpu.
wait方法在同步函数或者同步代码块中,释放锁
###06.16_多线程(线程的五种状态)
* 新建, 创建线程对象
start()
* 就绪, 就绪状态,有执行的资格,但没有执行权
抢到了cpu的执行权; 被其他的线程把cpu执行权抢走了
* 运行, 有执行资格和执行权
run()结束
stop()已经过去了
* 死亡, 线程对象变成垃圾
sleep()
wait()
* 阻塞,
###06.17_多线程(JDK1.5的新特性互斥锁)
* 1.同步
* 使用ReentrantLock类的lock()和unlock()方法进行同步
* 2.通信
* 使用ReentrantLock类的newCondition()方法可以获取Condition对象
* 需要等待的时候使用Condition的await()方法, 唤醒的时候用signal()方法
* 不同的线程使用不同的Condition, 这样就能区分唤醒的时候找哪个线程了
* 3.代码实现略
###06.01_什么是线程
* 线程是程序执行的一条路径, 一个进程中可以包含多条线程
* 多线程并发执行可以提高程序的效率, 可以同时完成多项工作
###06.02_多线程并行和并发的区别
* 并行就是两个任务同时运行,就是甲任务进行的同时,乙任务也在进行。(需要多核CPU)
* 并发是指两个任务都请求运行,而处理器只能按受一个任务,就把这两个任务安排轮流进行,由于时间间隔较短,使人感觉两个任务都在运行。
###06.03_多线程(多线程程序实现的方式1)
* 1.继承Thread
* 定义类继承Thread
* 重写run方法,把新线程要做的事写在run方法中
* 创建线程对象
* 开启新线程, 内部会自动执行run方法
public class Demo2_Thread {
public static void main(String[] args) {
MyThread mt = new MyThread();//4,创建自定义类的对象
mt.start();
//5,开启线程
for(int i = 0; i < 3000; i++) {
System.out.println("bb");
}
}
}
class MyThread extends Thread {//1,定义类继承Thread
public void run() {//2,重写run方法
for(int i = 0; i < 3000; i++) {//3,将要执行的代码,写在run方法中
System.out.println("aaaaaaaaaaaaaaaaaaaaaaaaaaaa");
}
}
}
###06.04_多线程(多线程程序实现的方式2)
* 2.实现Runnable
* 定义类实现Runnable接口
* 实现run方法,把新线程要做的事写在run方法中
* 创建自定义的Runnable的子类对象
* 创建Thread对象, 传入Runnable
* 调用start()开启新线程, 内部会自动调用Runnable的run()方法
public class Demo3_Runnable {
public static void main(String[] args) {
MyRunnable mr = new MyRunnable();//4,创建自定义类对象
//Runnable target = new MyRunnable();
Thread t = new Thread(mr);//5,将其当作参数传递给Thread的构造函数
t.start();
//6,开启线程
for(int i = 0; i < 3000; i++) {
System.out.println("bb");
}
}
}
class MyRunnable implements Runnable {//1,自定义类实现Runnable接口
@Override
public void run() {//2,重写接口Runnable的run方法
for(int i = 0; i < 3000; i++) {//3,将要执行的代码,写在run方法中
System.out.println("aaaaaaaaaaaa");
}
}
}
###06.05_多线程(两种方式的区别)
* 继承Thread
* 好处是:可以直接使用Thread类中的方法,代码简单
* 弊端是:如果已经有了父类,就不能用这种方法
* 实现Runnable接口
* 好处是:即使自己定义的线程类有了父类也没关系,因为有了父类也可以实现接口,而且接口是可以多实现的
* 弊端是:不能直接使用Thread中的方法需要先获取到线程对象后,才能得到Thread的方法,代码复杂
###06.06_多线程(匿名内部类实现线程的两种方式)
* 继承Thread类
new Thread() {//1,new 类(){}继承这个类
public void run() {//2,重写run方法
for(int i = 0; i < 3000; i++) {//3,将要执行的代码,写在run方法中
System.out.println("aaaaaaaaaaaaaaaaaaaaaaaaaaaa");
}
}
}.start();
* 实现Runnable接口
new Thread( new Runnable(){//1,new 接口(){}实现这个接口
public void run() {//2,重写run方法
for(int i = 0; i < 3000; i++) {//3,将要执行的代码,写在run方法中
System.out.println("bb");
}
}
} ).start();
###06.07_多线程(休眠线程)
* Thread.sleep(毫秒,纳秒), 控制当前线程休眠若干毫秒 1秒= 1000毫秒 1秒 = 1000 * 1000 * 1000纳秒 1000000000
* 会有InterruptedException异常
###06.08_多线程(守护线程)
* setDaemon(), 设置一个线程为守护线程, 该线程不会单独执行, 当其他非守护线程都执行结束后, 自动退出
###06.09_多线程(加入线程)
* join(), 使当前线程暂停, 等待指定的线程执行结束后, 当前线程再继续
* join(int), 可以指定等待时间毫秒值,之后再继续执行交替执行
###06.10_多线程(设置线程的优先级)
* setPriority()设置线程的优先级
//t1.setPriority(1);
//传数字和常量都可以 ,1最小,5默认,10最大
//t2.setPriority(10);
t1.setPriority(Thread.MAX_PRIORITY);
t2.setPriority(Thread.MIN_PRIORITY);
###06.11_多线程(同步代码块)
* 1.什么情况下需要同步
* 当多线程并发, 有多段代码同时执行时, 我们希望某一段代码执行的过程中CPU不要切换到其他线程工作. 这时就需要同步.
* 如果两段代码是同步的, 那么同一时间只能执行一段, 在一段代码没执行结束之前, 不会执行另外一段代码.
* 2.同步代码块
* 使用synchronized关键字加上一个锁对象来定义一段代码, 这就叫同步代码块
* 多个同步代码块如果使用相同的锁对象, 那么他们就是同步的
public class Demo_同步代码块 {
public static void main(String[] args) {
final Print p = new Print();
//用final修饰
new Thread(){
public void run(){
for (int i = 0; i < 500; i++) {
p.print1();
}
}
}.start();
new Thread(){
public void run(){
for (int i = 0; i < 500; i++) {
p.print2();
}
}
}.start();
}
}
class Print{
Deemmoo d = new Deemmoo();
public void print1(){
synchronized(d){ //锁对象可以是任意对象,但是被锁的代码需要保证是同一把锁,所以不能用匿名对象
System.out.print("黑");
System.out.print("马");
System.out.print("程");
System.out.print("序");
System.out.print("员");
System.out.print("\r\n");
}
}
public void print2(){
synchronized(d){
System.out.print("你");
System.out.print("真");
System.out.print("的");
System.out.print("很");
System.out.print("美");
System.out.print("\r\n");
}
}
}
class Deemmoo{
}
###06.12_多线程(同步方法)
* 使用synchronized关键字修饰一个方法, 该方法中所有的代码都是同步的 //同步方法只需要在方法上加synchronized关键字即可
###06.13_多线程(线程安全问题)
* 多线程并发操作同一数据时, 就有可能出现线程安全问题
* 使用同步技术可以解决这种问题, 把操作数据的代码进行同步, 不要多个线程一起操作
###06.14_多线程(单例设计模式)
* 单例设计模式:保证类在内存中只有一个对象。
* 如何保证类在内存中只有一个对象呢?
* (1)控制类的创建,不让其他类来创建本类的对象。private
* (2)在本类中定义一个本类的对象。Singleton s;
* (3)提供公共的访问方式。 public static Singleton getInstance(){return s}
* 饿汉式和懒汉式的区别
* 1,饿汉式是空间换时间,懒汉式是时间换空间
* 2,在多线程访问时,饿汉式不会创建多个对象,而懒汉式有可能会创建多个对象
* 单例写法两种:
* (1)饿汉式 开发用这种方式。
//饿汉式
class Singleton {
//1,私有构造函数
private Singleton(){}
//2,创建本类对象
private static Singleton s = new Singleton();
//3,对外提供公共的访问方法
public static Singleton getInstance() {
return s;
}
public static void print() {
System.out.println("11111111111");
}
}
* (2)懒汉式 面试写这种方式。多线程的问题?
//懒汉式, 单例的延迟加载模式
class Singleton {
//1,私有构造函数
private Singleton(){}
//2,声明一个本类的引用
private static Singleton s;
//3,对外提供公共的访问方法
public static Singleton getInstance() {
if(s == null)
//线程1,线程2 当时多线程的时候可能出现多个对象
s = new Singleton();
return s;
}
public static void print() {
System.out.println("11111111111");
}
}
* (3)第三种格式
class Singleton {
private Singleton() {}
public static final Singleton s = new Singleton(); //final是最终的意思,被final修饰的变量不可以被更改
}
###06.15_多线程(线程间的通信注意的问题)
* 1,在同步代码块中,用哪个对象锁,就用哪个对象调用wait方法
* 2,为什么wait方法和notify方法定义在Object类中? 因为锁对象可以是任意对象,Object是所有的类的基类,所以wait方法和notify方法需要定义在Object这个类中
* 3,sleep方法和wait方法的区别?
* a,sleep方法必须传入参数,参数就是时间,时间到了自动醒来
wait方法可以传入参数也可以不传入参数,传入参数就是在参数的时间结束后等待,不传入参数就是直接等待
* b,sleep方法在同步函数或同步代码块中,不释放锁,睡着了也抱着锁睡,一直占用cpu.
wait方法在同步函数或者同步代码块中,释放锁
###06.16_多线程(线程的五种状态)
* 新建, 创建线程对象
start()
* 就绪, 就绪状态,有执行的资格,但没有执行权
抢到了cpu的执行权; 被其他的线程把cpu执行权抢走了
* 运行, 有执行资格和执行权
run()结束
stop()已经过去了
* 死亡, 线程对象变成垃圾
sleep()
wait()
* 阻塞,
###06.17_多线程(JDK1.5的新特性互斥锁)
* 1.同步
* 使用ReentrantLock类的lock()和unlock()方法进行同步
* 2.通信
* 使用ReentrantLock类的newCondition()方法可以获取Condition对象
* 需要等待的时候使用Condition的await()方法, 唤醒的时候用signal()方法
* 不同的线程使用不同的Condition, 这样就能区分唤醒的时候找哪个线程了
* 3.代码实现略
相关文章推荐
- System.Diagnostics命名空间里的Debug类和Trace类的用途
- svn 清理失败 (clean up 失败) 的解决方法
- [LeetCode24]Swap Nodes in Pairs
- Angularjs scope
- win7通过easyBCD引导ubuntu
- Struts2学习笔记(3)之国际化
- Linux学习笔记--ls命令(查询目录中的内容)
- swoole & redis实现 Rest api
- 诡异的楼梯 hdu 1180
- iOS 类似于礼物说分类栏TableView,CollectionView联动的实现
- php 冒泡排序
- python自动化渗透
- Struts2学习笔记(2)之Result
- 【CODEFORCES】 C. Bits
- QPS UV PV
- [leetcode] 33. Search in Rotated Sorted Array
- java变量与数据类型
- Android应用Design Support Library完全使用实例
- 【慕课笔记】第七章 方法 第1节 如何定义JAVA中的方法
- NavigationView和DrawerLayout实现侧滑菜单栏