Java多线程总结_第1页
Java多线程总结_第2页
Java多线程总结_第3页
Java多线程总结_第4页
Java多线程总结_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1、进程和线程(1)多线程:一个应用程序有多条执行路径 进程: 正在运行的程序,是系统进行资源分配和调用的独立单位。 每一个进程都有它自己的内存空间和系统资源。 线程: 是进程中的单个顺序控制流,是一条执行路径。单线程:一个应用程序只有一条执行路径多线程:一个应用程序有多条执行路径并行和并发:前者是逻辑上同时发生,指在某一个时间内同时运行多个程序。后者是物理上同时发生,指在某一个时间点同时运行多个程序。多进程的意义?提高CPU的使用率多线程的意义?提高应用程序的使用率(2)Java程序的运行原理及JVM的启动是多线程的吗?A:Java命令去启动JVM,JVM会启动一个进程,该进程会启动一个主线

2、程去调用main方法B:JVM的启动是多线程的,因为它最低有两个线程启动了,主线程和垃圾回收线程。(3)多线程的实现方案A:继承Thread类步骤: a:自定义类MyThread继承Thread类。 b:MyThread类里面重写run()。c:创建对象 d:启动线程MyThread mt = new MyThread();mt.start();e: 为什么是run()方法呢? 不是类中的所有代码都需要被线程执行的。而这个时候,为了区分哪些代码能够被线程执行,java提供了Thread类中的run()用来包含那些被线程执行的代码调用run()方法为什么是单线程的呢?因为run()方法直接调用其

3、实就相当于普通的方法调用,所以你看到的是单线程的效果面试题:run()和start()的区别?run():仅仅是封装被线程执行的代码,直接调用是普通方法start():首先启动了线程,然后再由jvm去调用该线程的run()方法。B:实现Runnable接口步骤: a:自定义类MyRunnable实现Runnable接口 b:重写run()方法 c:创建MyRunnable类的对象d:创建Thread类的对象,并把C步骤的对象作为构造参数传递代码实现:MyRunnable my = new MyRunnable();Thread t = new Thread(my, "mame&quo

4、t;);t.start();(4)线程问题A:线程的调度a:分时调度b:抢占式调度 (Java采用的是该调度方式)B:获取和设置线程优先级a: 优先级 public final int getPriority():返回线程对象的优先级public final void setPriority(int newPriority):更改线程的优先级。b:默认是5c:范围是1-10d: 线程优先级高仅仅表示线程获取的 CPU时间片的几率高,但是要在次数比较多,或者多次运行的时候才能看到比较好的效果。C:线程对象的名称public final String getName():获取线程的名称。publi

5、c final void setName(String name):设置线程的名称public static Thread currentThread():返回当前正在执行的线程对象(针对不是Thread类的子类)D: 守护线程public final void setDaemon(boolean on):将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,Java 虚拟机退出。该方法必须在启动线程前调用。(5)线程的控制(常见方法)A:休眠线程:public static void sleep(long millis)ThreadSleep ts1 = new ThreadSl

6、eep();ts1.setName("name");ts1.start();public class ThreadStop extends Thread Overridepublic void run() Thread.sleep(10000);B:加入线程:public final void join():等待该线程终止(即该线程执行完毕才执行其它线程)ThreadJoin tj = new ThreadJoin();tj.setName("name");tj.start();tj1.join();C:礼让线程:public static void y

7、ield():暂停当前正在执行的线程对象,并执行其他线程。让多个线程的执行更和谐,但是不能靠它保证一人一次。ThreadYield ty= new ThreadYield();ty.setName("name");ty1.start();D:后台线程public final void setDaemon(boolean on) 将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,Java 虚拟机退出。 public final boolean isDaemon()测试该线程是否为守护线程。该方法必须在启动线程前调用。 E:终止线程(掌握) publi

8、c final void stop():让线程停止,已过时,但是还可以使用。public void interrupt():中断线程。把线程的状态终止,并抛出一个InterruptedException。代码实现:ThreadStop ts = new ThreadStop();ts.start();/ts.stop();/结束errupt();/中断(6)线程的生命周期A:新建B:就绪C:运行D:阻塞E:死亡(7)电影院卖票程序出问题A:为了更符合真实的场景,加入了休眠100毫秒。B:卖票问题a:同票多次性的CPU的一次操作必须是原子b:负数票随机性和延迟导致的(8)多线程安全问

9、题的原因(也是我们以后判断一个程序是否有线程安全问题的依据)A:是否有多线程环境B:是否有共享数据C:是否有多条语句操作共享数据(9)回顾以前的线程安全的类A:StringBufferB:VectorC:HashtableD:如何把一个线程不安全的集合类变成一个线程安全的集合类,用Collections工具类的方法即可。2、同步(1)同步问题A:同步synchronized(对象) 需要被同步的代码; 把多条语句操作共享数据的代码的部分给包起来 代码演示:Overridepublic void run() while (true) synchronized (obj) if (tickets

10、> 0) Thread.sleep(100); System.out.print(Thread.currentThread().getName()+ "正在出售第"+ (tickets-) + "张票"); 注意:同步可以解决安全问题的根本原因就在那个对象上。该对象如同锁的功能。多个线程必须是同一把锁。这里的锁对象可以是任意对象。B:同步的特点: 前提:多个线程 解决问题的时候要注意:多个线程使用的是同一个锁对象 同步的好处 同步的出现解决了多线程的安全问题。 同步的弊端 当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会

11、降低程序的运行C: 同步安全问题a: 同步代码块的锁对象是?任意对象。b:同步方法把同步加在方法上。这里的锁对象是thisc:静态同步方法把同步加在方法上。这里的锁对象是当前类的字节码文件对象(反射内容字节码文件对象)(2)JDK5以后的针对线程的锁定操作和释放操作虽然我们可以理解同步代码块和同步方法的锁对象问题,但是我们并没有直接看到在哪里加上了锁,在哪里释放了锁,为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock。 Lock:锁 void lock(): 获取锁。 void unlock():释放锁。 ReentrantLock是Lock的实现类.代码演示:priv

12、ate Lock lock = new ReentrantLock();Overridepublic void run() while (true) lock.lock();/ 加锁if (tickets > 0) Thread.sleep(100);System.out.println(Thread.currentThread().getName()+ "正在出售第" + (tickets-)+"张票"); finally lock.unlock();/ 释放锁(3)死锁问题的描述和代码体现死锁: 两个或两个以上的线程在争夺资源的过程中,发生的一

13、种相互等待的现象。代码演示:Overridepublic void run() if (flag) synchronized (MyLock.objA) System.out.println("if objA");synchronized (MyLock.objB) System.out.println("if objB"); else synchronized (MyLock.objB) System.out.println("else objB");synchronized (MyLock.objA) System.out.pri

14、ntln("else objA");(4)生产者和消费者多线程体现(线程间通信问题)以学生作为资源来实现的资源类:Student设置数据类:SetThread(生产者)获取数据类:GetThread(消费者)测试类:StudentDemo代码:public class SetThread implements Runnable private Student s;private int x = 0;public SetThread(Student s) this.s = s;Overridepublic void run() while (true) synchronize

15、d (s) if(s.flag) /判断有没有s.wait(); /等着,释放锁if (x % 2 = 0) = "林青霞" s.age = 27; else = "刘意"s.age = 30;x+; /x=1s.flag = true; /修改标记s.notify(); /唤醒线程 public class GetThread implements Runnable private Student s;public GetThread(Student s) this.s = s;Overridepublic void run

16、() while (true) synchronized (s) if(!s.flag)s.wait();/等待System.out.println( + "-" + s.age); s.flag = false;s.notify(); /唤醒 public class Student String name;int age;boolean flag; public class StudentDemo public static void main(String args) Student s = new Student();/创建资源SetThread st

17、= new SetThread(s); /设置和获取的类GetThread gt = new GetThread(s);Thread t1 = new Thread(st); /线程类Thread t2 = new Thread(gt);t1.start();/启动线程t2.start(); (5)线程组: 把多个线程组合到一起。它可以对一批线程进行分类管理,Java允许程序直接对线程组进行控制。private static void method () ThreadGroup tg = new ThreadGroup("这是一个新的组");MyRunnable my =

18、new MyRunnable(); /Runnable的实现类/ Thread(ThreadGroup group, Runnable target, String name)Thread t1 = new Thread(tg, my, "name1"); Thread t2 = new Thread(tg, my, "name2");ThreadGroup tg1 = t1.getThreadGroup();String name1 = tg1.getName();System.out.println(name1);System.out.println

19、(t2.getThreadGroup().getName();/public final void setDaemon(boolean on) 将该线程标记为守护线程或用户线程tg.setDaemon(true); /public static Thread currentThread()currentThread返回对当前正在执行的线程对象的引用。System.out.println(Thread.currentThread().getThreadGroup().getName();(6)线程池线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个

20、对象来使用。 实现线程池: A:创建一个线程池对象,控制要创建几个线程对象。 public static ExecutorService newFixedThreadPool(int nThreads) B:这种线程池的线程可以执行: 可以执行Runnable对象或者Callable对象代表的线程做一个类实现Runnable接口。 C:调用如下方法即可 Future<?> submit(Runnable task) <T> Future<T> submit(Callable<T> task)提交一个 Runnable 任务用于执行,并返回一个表示

21、该任务的 Future D:我就要结束 void shutdown() 启动一次顺序关闭,执行以前提交的任务,但不接受新任务。如果已经关闭,则调用没有其他作用。代码实现:ExecutorService pool = Executors.newFixedThreadPool(2);pool.submit(new MyRunnable();pool.submit(new MyRunnable();pool.shutdown();(6)多线程实现的第三种方案 方法一:继承Thread类来实现多线程new Thread() public void run() for (int x = 0; x <

22、; 100; x+) System.out.println(Thread.currentThread().getName() + ":"+ x);.start();方法二:实现Runnable接口来实现多线程new Thread(new Runnable() Overridepublic void run() for (int x = 0; x < 100; x+) System.out.println(Thread.currentThread().getName() + ":"+ x);) .start();方法三:内部类实现(两个run方法都可

23、以但是只执行一个)new Thread(new Runnable() Overridepublic void run() for (int x = 0; x < 100; x+) System.out.println("hello" + ":" + x);/其次) public void run() for (int x = 0; x < 100; x+) System.out.println("world" + ":" + x);/优先.start();3、定时器:可以让我们在指定的时间做某件事情,还

24、可以重复的做某件事情。 A:依赖Timer和TimerTask这两个类: Timer:定时 public Timer()创建一个新计时器。相关的线程不 作为守护程序运行。 public void schedule(TimerTask task,long delay) 安排在指定延迟后执行指定的任务 public void schedule(TimerTask task,long delay,long period) 安排指定的任务从指定的延迟后开始进行重复的固定延迟执行。 public void cancel() 终止此计时器,丢弃所有当前已安排的任务 TimerTask: 创建一个新的计时器任务B: 代码演示Timer t = new Timer();t.schedule(new MyTask(t), 3000);public class TimerDemo public static void main(St

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论