黑马程序员--Java基础--06多线程
2014-02-17 23:20
651 查看
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
1.多线程概念及创建
进程:正在执行的程序,特性为:动态性,并发性,独立性。
线程:是进程中用于控制程序执行的控制单元(执行路径,执行情景)进程中至少有一个线程。
注:编程时,必须确保线程不会妨碍到统一进程的其他线程。
线程的使用步骤:
(1)定义一个线程
(2)创建线程实例
(3)启动线程
(4)终止线程
线程的定义
(1)继承Thread类。
步骤:
定义类继承Thread。
复写Thread类中的run方法。
目的:将自定义代码存储在run方法。让线程运行。
调用线程的start方法,
该方法两个作用:启动线程,调用run方法。
(2)实现接口Runnable
步骤:
定义类实现Runnable接口
覆盖Runnable接口中的run方法。
将线程要运行的代码存放在该run方法中。
通过Thread类建立线程对象。
将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。
为什么要将Runnable接口的子类对象传递给Thread的构造函数。
因为,自定义的run方法所属的对象是Runnable接口的子类对象。
所以要让线程去指定指定对象的run方法。就必须明确该run方法所属对象。
调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。
2.线程状态,同步及安全
(1)线程的状态:被创建,可运行,阻塞,死亡。
(2)线程同步
如果一个资源被多个线程使用的话,不进行同步操作会造成读取严重错误,如果想让当前资源被一个线程使用时,不会受到其他线程影响,应该给当前资源上锁,java中使用sychronized关键字保证数据同步,格式为sychronized(指定收益的对象){同步代码块}
同步的前提:
必须要有两个或者两个以上的线程。
必须是多个线程使用同一个锁。
必须保证同步中只能有一个线程在运行。
线程示例:
生产消费者线程
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
1.多线程概念及创建
进程:正在执行的程序,特性为:动态性,并发性,独立性。
线程:是进程中用于控制程序执行的控制单元(执行路径,执行情景)进程中至少有一个线程。
注:编程时,必须确保线程不会妨碍到统一进程的其他线程。
线程的使用步骤:
(1)定义一个线程
(2)创建线程实例
(3)启动线程
(4)终止线程
线程的定义
(1)继承Thread类。
步骤:
定义类继承Thread。
复写Thread类中的run方法。
目的:将自定义代码存储在run方法。让线程运行。
调用线程的start方法,
该方法两个作用:启动线程,调用run方法。
//创建类MyThread继承Thread class MyThread extends Thread { public void run(){ //run方法里为线程启动后需要执行的代码 System.out.println("继承创建"); } } class TestThread { public static void main(String[] args) { //实例化线程对象 MyThread my = new MyThread(); //启动线程,start为初始化一个线程并执行run方法,如果为my.run()的话将不会建立线程 my.start(); } }
(2)实现接口Runnable
步骤:
定义类实现Runnable接口
覆盖Runnable接口中的run方法。
将线程要运行的代码存放在该run方法中。
通过Thread类建立线程对象。
将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。
为什么要将Runnable接口的子类对象传递给Thread的构造函数。
因为,自定义的run方法所属的对象是Runnable接口的子类对象。
所以要让线程去指定指定对象的run方法。就必须明确该run方法所属对象。
调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。
//创建类MyRunnable实现接口Runnable class MyRunnable implements Runnable { public void run(){ //run方法里为线程启动后需要执行的代码 System.out.println("实现接口创建"); } } class TestRunnable { public static void main(String[] args) { //创建接口myb MyRunnable myb = new MyRunnable(); //将myb作为参数传入Thread,实例化线程对象 Thread my = new Thread(myb); //启动线程 my.start(); } }
2.线程状态,同步及安全
(1)线程的状态:被创建,可运行,阻塞,死亡。
(2)线程同步
如果一个资源被多个线程使用的话,不进行同步操作会造成读取严重错误,如果想让当前资源被一个线程使用时,不会受到其他线程影响,应该给当前资源上锁,java中使用sychronized关键字保证数据同步,格式为sychronized(指定收益的对象){同步代码块}
//单例懒汉式 class Single { //定义本类对象 private static Single s = null; //私有化构造方法 private Single(){} public static Single getInstance() { //将本类作为收益对象传入关键字,对象如同锁。持有锁的线程可以在同步中执行。 //没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。 synchronized(Single.class) { //保证线程执行完此代码块 if(s==null) s = new Single(); } return s; } }< ada6 /span>
同步的前提:
必须要有两个或者两个以上的线程。
必须是多个线程使用同一个锁。
必须保证同步中只能有一个线程在运行。
//死锁线程 public class Dead { public static void main(String[] args) { new Thread(new Dead1(true)).start();//线程1 new Thread(new Dead1(false)).start();//线程2 } } class Dead1 implements Runnable { // 定义静态对象使线程共享 static Object ob1 = new Object(); static Object ob2 = new Object(); // 定义标示 private boolean flag; // 定义含标示的构造方法 Dead1(boolean flag) { this.flag = flag; } public void run() { if (flag) { while (true) { //同步中嵌套同步易发生死锁现象,当flag为真时运行下列代码,收益对象为ob1, //但当代码到此进入冻结状态释放运行权限给线程2时,收益对象为ob2,同时代码 //进入冻结状态释放运行权后,线程1所需收益对象ob2还在线程2中无法释放,而 //线程2也需收益对象ob1以便运行后续代码,因此线程进入死锁状态 synchronized (ob1) { System.out.println("aaa.."); synchronized (ob2) { System.out.println("bbb.."); } } } } else { while (true) { synchronized (ob2) { System.out.println("ccc.."); synchronized (ob1) { System.out.println("ddd.."); } } } } } }
线程示例:
生产消费者线程
class Res { //商品计数 private int sum; //定义标示符操作生产者与消费者前后顺序 private boolean flag = false; //Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。 //此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关的 Condition 对象。 private Lock lock = new ReentrantLock(); //生成Condition对象,替换Object中的wait,notify notifyAll Condition con_pro = lock.newCondition(); Condition con_con = lock.newCondition(); public void set()throws InterruptedException{ //上锁 lock.lock(); try{ while(flag) //生产者冻结 con_pro.await(); //商品计数 this.sum++; System.out.println(Thread.currentThread().getName()+"生产商品:"+sum); this.flag = true; //消费者进入可执行状态 con_con.signal(); }finally{ //解锁 lock.unlock(); } } public void out()throws InterruptedException{ //上锁 lock.lock(); try{ while(!flag) //消费者冻结 con_con.await(); System.out.println(Thread.currentThread().getName()+"消费商品:"+sum); this.flag = false; //生产者进入可执行状态 con_pro.signal(); }finally{ //解锁 lock.unlock(); } } } //生产者 class Produce implements Runnable { private Res res; Produce(Res res){ this.res = res; } public void run(){ while(true){ try{ res.set(); }catch(Exception e){ } } } } //消费者 class Consumer implements Runnable { private Res res; Consumer(Res res){ this.res = res; } public void run(){ while(true){ try{ res.out(); }catch(Exception e){ } } } } class Test3 { public static void main(String[] args) { Res r = new Res(); Produce p = new Produce(r); Consumer c = new Consumer(r); //两个生产线同时生产 new Thread(p).start(); new Thread(p).start(); //两个消费者同时消费 new Thread(c).start(); new Thread(c).start(); } }
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
相关文章推荐
- 黑马程序员——Java基础__多线程(上)
- 黑马程序员java基础之多线程
- 黑马程序员——java基础——多线程
- 黑马程序员-JAVA基础-多线程间的通信、等待唤醒机制和新特性
- 黑马程序员——java基础_多线程
- 黑马程序员_java基础--多线程
- 黑马程序员_java基础笔记(04)...多线程
- 黑马程序员——Java基础:多线程及其应用
- 黑马程序员——Java基础:多线程
- 黑马程序员 Java学习总结之多线程基础
- 黑马程序员——Java基础---多线程详解
- [黑马程序员]--Java语言基础-多线程
- 黑马程序员_Java基础_多线程1
- 黑马程序员---Java基础学习笔记(多线程-后篇)
- 黑马程序员——Java基础——多线程
- 黑马程序员:Java基础——多线程的死锁问题
- 黑马程序员——java基础拾遗之多线程(二) 线程同步、线程通信
- 黑马程序员————java基础(多线程)
- 黑马程序员——Java基础---多线程Thread,Component
- 黑马程序员:Java基础——多线程的停止与守护以及Join,优先级和yield方法