多线程
Posted 旺仔成长记
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程相关的知识,希望对你有一定的参考价值。
1、JDK5以后的针对线程的锁定操作和释放操作
A:为了更清晰表达在哪里如何加锁及释放锁 B:Lock锁 lock():加锁 unlock():释放锁 C:ReentrantLock 是 Lock 的实现类 private Lock lock = new ReentrantLock(); lock.lock(); //加锁 ... //加锁代码 lock.unlock(); //释放锁
2、死锁问题的描述和代码体现
指两个或两个以上的线程在执行过程中,因争夺资源产生的一种互相等待现象(如果出现了同步嵌套,就容易 产生死锁问题)
3、生产者和消费者多线程体现(线程间通信问题)
A:不同种类的线程间针对同一个资源的操作 代码实现: //在外界把这个数据创建出来,通过构造方法传递给其它类 Student s = new Student(); GetThread gt = new GetThread(s); SetThread st = new SetThread(s); B:以学生作为资源来实现的 资源类:Student 设置数据类:SetThread(生产者) 获取数据类:GetThread(消费者) 测试类:StudentDemo 代码: A:最基本的版本,只有一个数据。 B:改进版本,给出了不同的数据,并加入了同步机制 C:等待唤醒机制改进该程序,让数据能够实现依次的出现 wait() notify() notifyAll() (多生产多消费) D:等待唤醒机制的代码优化。把数据及操作都写在了资源类中 注:这些方法调用必须通过锁对象调用,而我们刚才使用的锁对象是任意锁对象。 所以,这些方法必须定义在Object类中。
4、线程组
把多个线程组合到一起。它可以对一批线程进行分类管理,Java允许程序直接对线程组进行控制。 public final ThreadGroup getThreadGroup():返回该线程所属的线程组 ThreadGroup tg = mt.getThreadGroup(); public final String getName():返回此线程组的名称 String name1 = tg.getName(); 注:默认情况下,所有线程都属于同一个组 ThreadGroup(String name):修改线程所在的组 MyRunnable my = new MyRunnable(); ThreadGroup tg2 = new ThreadGroup("newThreadGroup"); Thread t = new Thread(tg2, my, "threadName"); tg2.get...
5、线程池
程序启动一个新线程成本比较高,使用线程池可以很好的提高性能,尤其是创建大量生存期很短的线程时, 更应该考虑使用线程池。 线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象 来使用。 在JDK5之前,我们必须手动实现自己的线程池,从JDK5开始,Java内置支持线程池。 线程池的实现: A: 创建一个线程池对象,控制要创建几个线程对象 public static ExecutorService newFixedThreadPool(int nThreads) B: 这种线程池可以执行 可以执行Runnable对象或者Callable对象代表的线程 做一个类实现Runnable接口 C: 调用如下方法即可 Future<?> submit(Runnable task) Future submit(Callable task) D: 非要结束 pool.shutdown(); 代码案例: public static void main(String[] args){ //创建一个线程池对象,控制要创建几个线程对象 ExecutorService pool = new ExecutorService.newFixedThreadPool(2); //可以执行Runnable对象或者Callable对象代表的线程 pool.submit(new MyRunnable()); pool.submit(new MyRunnable()); //结束线程池 pool.shutdown(); }
6、多线程实现的第三种方案
实现Callable接口,与Runnable类似 代码案例--10
7、匿名内部类方式实现多线程
A:new Thread(){代码...}.start(); B:new Thread(new Runnable(){代码...}){}.start(); 代码案例: //继承Thread类来实现多线程 new Thread(){ public void run(){ ... } }.start(); //实现Runnable接口来实现多线程 new Thread(new Runnable(){ public void run(){ ... } }){}.start();
8、定时器
可在指定时间执行某任务,还可以重复执行 依赖Timer 和TimerTask Timer:定时 public Timer() public void schedule(TimerTask task, long delay) public void schedule(TimerTask task) public void cancel(); 代码案例: public static void main(String[] args){ //创建定时器对象 Timer t = new Timer(); //3秒后执行爆炸任务 //t.schedule(new MyTask(), 3000); //结束任务 t.schedule(new MyTask(t), 3000); } class MyTask extends TimerTask(){ private Timer t; public MyTask(){} public MyTask(Timer t){ this.t = t; } public void run(){ System.out.println("beng!!!"); t.cancel(); } }
9、多线程的面试题
A:多线程有几种实现方案,分别是哪几种? 继承Thred类 实现Runnable接口 扩展:实现Callable接口,需要和线程池结合 B:同步有几种方式,分别是什么? 两种 同步代码块 同步方法 C:启动一个线程是run()还是start()?他们的区别是? start(); run():封装了被线程执行的代码,直接调用仅仅是普通方法调用 start():启动线程,并由JVM自动调用run()方法 D:sleep()和wait()方法的区别 sleep():必须指定时间。不释放锁 wait():可以不指定时间,也可以指定时间,释放锁。 E:为什么wait(),notify(),notifyAll()等方法定义在Object类中 因为这些方法的调用是依赖锁对象的,而同步代码块的锁对象是任意锁。 F:线程的生命周期 新建--就绪--运行--死亡 新建--就绪--运行--阻塞--就绪--运行--死亡 建议画图解释
以上是关于多线程的主要内容,如果未能解决你的问题,请参考以下文章