多线程
2015-06-25 23:00
393 查看
(一)、进程、线程、多进程的概念
进程:是一个正在执行中的程序。每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者叫一个控制单元。
线程:就是进程中的一个独立的控制单元。线程在控制着进程的执行。
注意点:
1、一个进程中至少有一个线程。
2、一个进程中可以有多个执行路径,称之为多线程。
3、开启多个线程是为了同时运行多部分代码,每一个线程都有自己运行的内容,这个内容可以称为线程要执行的任务。
多线程的好处:解决了多部分代码同时运行的问题。
多线程的弊端:线程太多,会导致效率的降低。
什么是”并行”和”并发”:
1.”并行”是指逻辑上一起在执行,它强调的是在”同一段时间内”一起运行的程序;
2.”并发”是指物理上的抢占同一资源。它强调的是在”同一时刻时”一起抢占系统的某个共享资源;
(二)、线程的创建方式
创建线程方式一:继承Thread类
1. 定义一个类继承Thread类。
2. 覆盖Thread类中的run方法。
3. 直接创建Thread的子类对象创建线程。
4. 调用start方法开启线程并调用线程的任务run方法执行。
创建线程方式二:实现Runnable接口
1. 定义类实现Runnable接口。
2. 覆盖接口中的run方法,将线程的任务代码封装到run方法中。
3. 通过Thread类创建线程对象,并将Runnable接口的子类对象作为Thread类的构造函数的参数进行传递。为什么?因为线程的任务都封装在Runnable接口子类对象的run方法中。所以要在线程对象创建时就必须明确要运行的任务。
4. 调用线程对象的start方法开启线程。
实现Runnable接口的好处:
1. 将线程的任务从线程的子类中分离出来,进行了单独的封装,按照面向对象的思想将任务封装成对象。
2. 避免了Java单继承的局限性。所以,创建线程的第二种方式较为常用。
(三)、线程安全问题
线程安全问题产生的原因?
1. 多个线程在操作共享的数据。
2. 操作共享数据的线程代码有多条。
当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算,就会导致线程安全问题的产生。
线程安全问题的解决方案?
将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,其他线程不可以参与运算。必须要当前线程把这些代码都执行完毕后,其他线程才可以参与运算。
格式有两种:
synchronized(对象){
需要被同步的代码;
}
在函数上加上synchronized修饰符
很好的解决了线程安全问题,但是同步的弊端是当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率。
需求:储户,两个,每个都到银行存钱,每次存100,共存三次。
(四)、多线程下的单例设计模式
饿汉式
懒汉式
比较:饿汉式不存在安全问题,因为不存在多个线程共同操作数据的情况,懒汉式存在安全问题,可以使用同步函数解决, 但若直接使用同步函数,则效率较低,因为每次都需要判断,需要提前判断以提高效率。
(五)、线程间的通信–生产者和消费者
1. wait():让线程处于冻结状态,被wait的线程会被存储到线程池中。
2. notify():唤醒线程池中的一个线程(任何一个都有可能)。
3. notifyAll():唤醒线程池中的所有线程。
4、wait和sleep区别?
1)wait可以指定时间也可以不指定。sleep必须指定时间。
2)在同步中时,对CPU的执行权和锁的处理不同。
wait:释放执行权,释放锁。
sleep:释放执行权,不释放锁。
多生产着和多消费着问题
进程:是一个正在执行中的程序。每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者叫一个控制单元。
线程:就是进程中的一个独立的控制单元。线程在控制着进程的执行。
注意点:
1、一个进程中至少有一个线程。
2、一个进程中可以有多个执行路径,称之为多线程。
3、开启多个线程是为了同时运行多部分代码,每一个线程都有自己运行的内容,这个内容可以称为线程要执行的任务。
多线程的好处:解决了多部分代码同时运行的问题。
多线程的弊端:线程太多,会导致效率的降低。
什么是”并行”和”并发”:
1.”并行”是指逻辑上一起在执行,它强调的是在”同一段时间内”一起运行的程序;
2.”并发”是指物理上的抢占同一资源。它强调的是在”同一时刻时”一起抢占系统的某个共享资源;
(二)、线程的创建方式
创建线程方式一:继承Thread类
1. 定义一个类继承Thread类。
2. 覆盖Thread类中的run方法。
3. 直接创建Thread的子类对象创建线程。
4. 调用start方法开启线程并调用线程的任务run方法执行。
class Test extends Thread { private String name; public Test(String name) { this.name=name; } public void run() { for (int x=0;x<100 ;x++ ) { System.out.println((Thread.currentThread()==this)+"----"+this.getName()+"run----"+x); } } } class ThreadTest { public static void main(String[] args) { Test t1=new Test("xiaomi"); Test t2=new Test("liming"); t1.start(); t2.start(); for(int x=0;x<100;x++) { System.out.println("main------"+x); } } }
创建线程方式二:实现Runnable接口
1. 定义类实现Runnable接口。
2. 覆盖接口中的run方法,将线程的任务代码封装到run方法中。
3. 通过Thread类创建线程对象,并将Runnable接口的子类对象作为Thread类的构造函数的参数进行传递。为什么?因为线程的任务都封装在Runnable接口子类对象的run方法中。所以要在线程对象创建时就必须明确要运行的任务。
4. 调用线程对象的start方法开启线程。
实现Runnable接口的好处:
1. 将线程的任务从线程的子类中分离出来,进行了单独的封装,按照面向对象的思想将任务封装成对象。
2. 避免了Java单继承的局限性。所以,创建线程的第二种方式较为常用。
class Demo implements Runnable{ public void run(){ show(); } public void show(){ for(int x = 0; x < 100; x++){ System.out.println(Thread.currentThread().getName() + "---" + x); } } } class ThreadDemo{ public static void main(String[] args){ Demo d = new Demo(); Thread t1 = new Thread(d); Thread t2 = new Thread(d); t1.start(); t2.start(); } }
(三)、线程安全问题
线程安全问题产生的原因?
1. 多个线程在操作共享的数据。
2. 操作共享数据的线程代码有多条。
当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算,就会导致线程安全问题的产生。
线程安全问题的解决方案?
将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,其他线程不可以参与运算。必须要当前线程把这些代码都执行完毕后,其他线程才可以参与运算。
格式有两种:
synchronized(对象){
需要被同步的代码;
}
在函数上加上synchronized修饰符
很好的解决了线程安全问题,但是同步的弊端是当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率。
需求:储户,两个,每个都到银行存钱,每次存100,共存三次。
class Bank{ private int sum ; public void add(int num){ synchronized(this ){ sum = sum + num; System. out.println("sum = " + sum); } } } class Cus implements Runnable{ private Bank b = new Bank(); public void run(){ for(int x = 0; x < 3; x++){ b.add(100); } } } class BankDemo{ public static void main(String[] args){ Cus c = new Cus(); Thread t1 = new Thread(c); Thread t2 = new Thread(c); t1.start(); t2.start(); } }
(四)、多线程下的单例设计模式
饿汉式
class Single { private static final Single s=new Single(); private Single(){} public static Single getInstance() { return s; } }
懒汉式
class Single { private static Single s=null; private Single(){} public static Single getInstance() { if(s==null) { synchronized(Single.class) { if(s==null) //---->A s=new Single(); } } return s; } }
比较:饿汉式不存在安全问题,因为不存在多个线程共同操作数据的情况,懒汉式存在安全问题,可以使用同步函数解决, 但若直接使用同步函数,则效率较低,因为每次都需要判断,需要提前判断以提高效率。
(五)、线程间的通信–生产者和消费者
1. wait():让线程处于冻结状态,被wait的线程会被存储到线程池中。
2. notify():唤醒线程池中的一个线程(任何一个都有可能)。
3. notifyAll():唤醒线程池中的所有线程。
4、wait和sleep区别?
1)wait可以指定时间也可以不指定。sleep必须指定时间。
2)在同步中时,对CPU的执行权和锁的处理不同。
wait:释放执行权,释放锁。
sleep:释放执行权,不释放锁。
多生产着和多消费着问题
class Resource{ private String name ; private int count = 1; private boolean flag = false; public synchronized void set(String name){ while(flag ) try{ this.wait(); } catch(InterruptedException e){ e.printStackTrace(); } this.name = name + count; count++; System.out.println(Thread.currentThread().getName() + "...生产者..." + this. name); flag = true ; notifyAll(); } public synchronized void out(){ while(!flag ) try{ this.wait(); } catch(InterruptedException e){ e.printStackTrace(); } flag = false ; notifyAll(); System.out.println(Thread.currentThread().getName() + "...消费者..." + this. name); } } class Producer implements Runnable{ private Resource r ; Producer(Resource r){ this.r = r; } public void run(){ while(true ){ r.set( "馄饨"); } } } class Consumer implements Runnable{ private Resource r ; Consumer(Resource r){ this.r = r; } public void run(){ while(true ){ r.out(); } } } class ProducerConsumerDemo { public static void main(String[] args){ Resource r = new Resource(); Producer pro = new Producer(r); Consumer con = new Consumer(r); Thread t0 = new Thread(pro); Thread t1 = new Thread(pro); Thread t2 = new Thread(con); Thread t3 = new Thread(con); t0.start(); t1.start(); t2.start(); t3.start(); } }
相关文章推荐
- MyEclipse下载,安装,激活和简单使用
- BZOJ 3992 序列统计
- Discover browser developer tools
- LeetCode之“链表”:Linked List Cycle && Linked List Cycle II
- Linux touch 命令
- 使用ViewPager+Fragment实现选项卡切换效果
- Publishing via GitHub
- CentOS修改22默认端口 SSH默认端口
- Django 后台表单标签的自定义
- 在职一座山,离职一座碑
- LoadRunner Error code 10053,Software caused connection abort
- [LeetCode][JavaScript]Sqrt(x)
- 【深入JVM】JVM工具之JCONSOLE
- 【学习笔记】【C语言】返回指针的函数
- SQL数据库语句
- 数据库优化技巧
- Json概述以及python对json的相关操作
- 在烟台的一年
- FFmpeg解码多线程
- leetcode刷题 总结,记录,备注 53