黑马程序员------多线程

发布时间:2016-12-9 23:27:51 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"黑马程序员------多线程",主要涉及到黑马程序员------多线程方面的内容,对于黑马程序员------多线程感兴趣的同学可以参考一下。

----------android培训、java培训、期待与您交流! ---------- 多线程 1:多线程的概念 就是应用程序有多条执行路径 进程:正在运行的程序。 线程:进程的执行路径,执行路径。 2:如何使用多线程程序 A:方式1 继承Thread类。 a:创建一个类继承Thread类 b:重写Thread类的run方法。 run()方法里面才是封装县城的代码。 B:代码体现: public class MyThread extends Thread { public void run() { for(int x=0; x<100; x++) { System.out.println(getName()+"---"+"hello"+x); } } } public MyThreadTest { public static void main(String[] args) { MyThread my1 = new MyThread(); MyThread my2 = new MyThread(); my1.start(); my2.start(); } }B:方式2 实现Runnable接口 代码体现: public class MyRunnable implements Runnable { public void run() { public void run() { for(int x=0; x<100; x++) { System.out.println(Thread.currentThread().get()+"---"+"hello"+x); } } } } public class MyRunnableTest { public static void main(String[] args) { MyRunnable my = new MyRunnable(); Thread t1 = new Thread(my); Thread t2 = new Thread(my); t1.start(); t2.start(); } }注意:既然有了继承Thread类的方式,为什么还要有实现Runnable接口的方式?   A:避免的单继承的局限性   B:实现接口的方式,只创建了一个资源对象,更好的实现了数据和操作的分离。   一般我们选择第二种方式。 (3)方法 staticThreadcurrentThread();获取当前线程对象 StringgetName();返回线程名称 voidsetName(String);设置线程名称,也可以通过构造方法设置名称。 staticvoidsleep(long millis);让当前正在执行的线程休眠指定的 毫秒。 (4)线程的随机性原理 多个程序其实是CPU的在做着高效切换执行的。 (5)线程的生命周期 新建 :线程对象已经创建,还没有在其上调用start()方法。 就绪:当线程有资格运行,但调度程序还没有把它选定为运行线程时线程所处的状态。当start()方法调用时 ,线程首先进入可运行状态。在线程运行之后或者从阻塞、等待或睡眠状态回来后,也返回到可运 行状态。 运行:线程调度程序从可运行池中选择一个线程作为当前线程所处的状态。这也是线程进入运行状态的唯一 一种方式。 阻塞:这是线程有资格运行时它所处的状态。实际上这个三状态组合为一种,其共同点是:线程仍旧是活的 , 但是当前没有条件运行。 死亡:当线程的run()方法完成时就认为它死去。这个线程对象也许是活的,但是,它已经不是一个单独执行 的线程。线程一旦死亡,就不能复生。如果在一个死去的线程上调用start()方法,会抛出 java.lang.IllegalThreadStateException异常。 (6)线程安全问题 A:卖票案例 a:方式1继承Thread类。 public class TicketThread extends Thread { private static int tickets = 200; @Override public void run() { while (true) { if (tickets > 0) { System.out.println(getName() + "正在出售第" + (tickets--) + "张票"); } } } } public class ThreadTest { public static void main(String[] args) { TicketThread tt1 = new TicketThread(); TicketThread tt2 = new TicketThread(); TicketThread tt3 = new TicketThread(); TicketThread tt4 = new TicketThread(); tt1.setName("窗口1"); tt2.setName("窗口2"); tt3.setName("窗口3"); tt4.setName("窗口4"); tt1.start(); tt2.start(); tt3.start(); tt4.start(); } } b:方式2 实现Runnable接口 public class TicketRunnable implements Runnable { private int tickets = 200; @Override public void run() { while (true) { if (tickets > 0) { System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票"); } } } } public class RunnableTest { public static void main(String[] args) { TicketRunnable tr = new TicketRunnable(); Thread t1 = new Thread(tr); Thread t2 = new Thread(tr); Thread t3 = new Thread(tr); Thread t4 = new Thread(tr); t1.setName("窗口1"); t2.setName("窗口2"); t3.setName("窗口3"); t4.setName("窗口4"); t1.start(); t2.start(); t3.start(); t4.start(); } } B:线程的安全问题的产生的条件 a:有共享数据 b:共享数据被多条语句操作 c:在多线程环境中 (7)线程安全问题的解决方案: A:同步代码块 synchronized(锁对象) { 被同步的代码 } B:同步方法 把synchronized加在方法上。 注意:   同步代码块的锁对象是什么?   同步代码块的锁是任意对象。     同步方法:就是把锁加在方法上 格式:在方法上加synchronized关键字 同步方法的锁对象是谁? this对象  静态方法的锁对象是谁呢? 是当前类的字节码文件对象。 类名.class - Class类型的对象 以后我们用同步代码块还是同步方法呢? 被同步的内容越少越好,所以,一般使用同步代码块。 如果一个方法内部全部都被同步了,那么,可以考虑使用同步方法。 public class TicketRunnable implements Runnable { private static int tickets = 100; private Object obj = new Object(); private Demo d = new Demo(); @Override public void run() { int x = 0; while (true) { if (x % 2 == 0) { // synchronized (this) { synchronized (TicketRunnable.class) { if (tickets > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票"); } } } else { check(); } x++; } } // private synchronized void check() { // if (tickets > 0) { // try { // Thread.sleep(100); // } catch (InterruptedException e) { // e.printStackTrace(); // } // System.out.println(Thread.currentThread().getName() + "正在出售第" // + (tickets--) + "张票"); // } // } private static synchronized void check() { if (tickets > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票"); } } } 一般推荐使用同步代码块。 (8)线程间的通信问题 学生类: public class Student { private String name; private int age; private boolean flag = false; public synchronized void set(String name, int age) { // 如果有数据就等待 if (this.flag) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 设置值 this.name = name; this.age = age; // 修改标记 this.flag = true; this.notify(); } public synchronized void get() { // 如果没有数据就等待 if (!this.flag) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 获取值 System.out.println(this.name + "***" + this.age); // 修改标记 this.flag = false; this.notify(); } } 设置学生属性的类: public class SetStudent implements Runnable { private Student s; public SetStudent(Student s) { this.s = s; } @Override public void run() { // t1过来了 int x = 0; while (true) { if (x % 2 == 0) { s.set("林青霞", 26); } else { s.set("刘意", 29); } x++;// x=1,t2抢到;x=2,t2抢到; } } } 获取学生属性的类: public class GetStudent implements Runnable { private Student s; public GetStudent(Student s) { this.s = s; } @Override public void run() { while (true) { s.get(); } } } 测试类: public class StudentTest { public static void main(String[] args) { Student s = new Student();// 资源类 SetStudent ss = new SetStudent(s); GetStudent gs = new GetStudent(s); Thread t1 = new Thread(ss); Thread t2 = new Thread(gs); t1.start(); t2.start(); } }(9)常见的方法 优先级 线程默认优先级是5。范围是1-10。 public final int getPriority():获取线程优先级   public final void setPriority(int newPriority):更改线程的优先级。 暂停线程 public static void yield():暂停当前正在执行的线程对象,并执行其他线 加入线程 public final void join():等待该线程终止。    一旦有join()线程,那么,其他的线程必须都等待,知道该线程结束 守护线程 public static void yield() (10)面试题: 1:sleep() 和 wait() 有什么区别?   wait():是Object类的方法,可以不用传递参数。释放锁对象。     sleep():是Thread类的静态方法,需要传递参数。不释放锁对象 /*  :2 面试题:请写出一个死锁的代码。  */ public class DieLockDemo { public static void main(String[] args) { DieLock d1 = new DieLock(true); DieLock d2 = new DieLock(false); d1.start(); d2.start(); } }----------android培训、java培训、期待与您交流! ---------- 详细请查看:http://edu.csdn.net

上一篇:servlet/JSP自定义标签/Filter/Listener/新特性
下一篇:迭代器介绍

相关文章

相关评论