Java多线程与并发库高级应用
Posted wq3435
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java多线程与并发库高级应用相关的知识,希望对你有一定的参考价值。
1.传统线程机制的回顾
1.1创建线程的两种传统方式
在Thread子类覆盖的run方法中编写运行代码
// 1.使用子类,把代码放到子类的run()中运行
Thread thread = new Thread() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
}
}
};
thread.start();
>涉及一个以往的知识点:能否在run方法声明上抛出异常,以便省略run方法内部对Thread.sleep()语句的try...catch处理InterrunptedException?
在覆写祖先类方法或实现接口方法(覆写run方法,而本源run方法没有做抛出声明),所以你无法做抛出声明
在传递给Thread对象的Runnable对象的run方法中编写代码
public Thread(Runnable target) { init(null, target, "Thread-" + nextThreadNum(), 0); }
在init方法中对Thread对象的target进行复制
Thread的run方法
/** * If this thread was constructed using a separate * <code>Runnable</code> run object, then that * <code>Runnable</code> object‘s <code>run</code> method is called; * otherwise, this method does nothing and returns. * <p> * Subclasses of <code>Thread</code> should override this method. * * @see #start() * @see #stop() * @see #Thread(ThreadGroup, Runnable, String) */ @Override public void run() { if (target != null) { target.run(); } }
//2.代码放在Runnable对象中,Runnable是代码运行的宿主
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
}
}
});
thread2.start();
>问题:如果在Thread子类覆盖的run方法总编写了运行代码,也为Thread子类对象传递了一个Runnable对象,那么,线程执行的是哪个run方法?
子类的run()覆盖了父类的run(),如果没有覆盖父类的run(),会找Runnable
//3.使用的是子类中的run方法 new Thread(new Runnable() { @Override public void run() { while(true){ try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("runnable :"+Thread.currentThread().getName()); } } }){ public void run() { while(true){ try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("thread :"+Thread.currentThread().getName()); } }; }.start();
>涉及到一个以往的知识点:匿名内部类对象的构造方法如何调用父类的非默认构造方法?
>多线程机制会提高程序的运行效率么?
单个cpu下不会提高运行效率,反而性能更低
Java中sleep和wait的区别
① 这两个方法来自不同的类分别是,sleep来自Thread类,和wait来自Object类。
sleep是Thread的静态类方法,谁调用的谁去睡觉,即使在a线程里调用b的sleep方法,实际上还是a去睡觉,要让b线程睡觉要在b的代码中调用sleep。
② 锁: 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
sleep不出让系统资源;wait是进入线程等待池等待,出让系统资源,其他线程可以占用CPU。一般wait不会加时间限制,因为如果wait线程的运行资源不够,再出来也没用,要等待其他线程调用notify/notifyAll唤醒等待池中的所有线程,才会进入就绪队列等待OS分配系统资源。sleep(milliseconds)可以用时间指定使它自动唤醒过来,如果时间不到只能调用interrupt()强行打断。
Thread.sleep(0)的作用是“触发操作系统立刻重新进行一次CPU竞争”。
③ 使用范围:wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用。
synchronized(x){
x.notify()
//或者wait()
}
2.传统定时器技术回顾(jdk1.5以前)
public class TraditionalTimerTest {
static int count = 0;
public static void main(String[] args) {
//10秒后开始执行,每隔3秒执行一次
new Timer().schedule(new TimerTask() {
@Override
public void run() {
System.out.println("bombing...");
}
}, 10000,3000);
/**
* 需求:2秒,4秒间隔执行定时任务
*/
class MyTimerTask extends TimerTask{
@Override
public void run() {
count = (count+1)%2;
System.out.println("bombing...");
new Timer().schedule(new MyTimerTask(), 2000 + 2000*count);
}
}
new Timer().schedule(new MyTimerTask(), 2000);
while(true){
try {
System.out.println(new Date().getSeconds());
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//quartz 周一~周五执行任务,周六日不执行
}
}
以上是关于Java多线程与并发库高级应用的主要内容,如果未能解决你的问题,请参考以下文章
(黑马Java多线程与并发库高级应用)05 线程范围内共享变量的概念与作用