您的位置:首页 > 职场人生

线程高级应用-心得2-同步锁讲解及面试题案例分析

2017-01-08 13:36 676 查看
1.引入同步锁





2.同步锁案例分析

package com.itcast.family;

/*
* 传统线程的使用及注意事项
*/
public class TraditionalThread {

public static void main(String[] args) {

//一、线程1;直接new一个thread子类,让子类run方法覆盖父类的run()
Thread thread1 = new Thread(){

@Override
public void run() {
while(true){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//线程1获取到的线程名字是从0开始的,即thread1--1:Thread-0
System.out.println("thread1--1:"+Thread.currentThread().getName());
//在这里this 即代表thread对象,因为直接new的是thread类
System.out.println("thread1--2:"+this.getName());
}
}

};
thread1.start();
/*
* 运行结果:
* thread1--1:Thread-0
thread1--2:Thread-0
*/

//二、线程2;不new子类,给Thread类传一个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("thread2--1:"+Thread.currentThread().getName());
/*这里就不能用this了,this在这里代表Runable对象,不是Thread线程对象了,
* Runable是线程运行的代码宿主;所以要想获取该线程的名字一般都是用
* Thread.currentThread().getName();而不是this.getName()
*/
//                    System.out.println("thread2--2:"+this.getName());
}
}

});
thread2.start();
/*
* 运行结果:
* thread2--1:Thread-1
thread1--1:Thread-0
thread1--2:Thread-0
*/

/*
* 以上两种new 线程的方法有什么不同?
*   第一种是new Thread线程对象,通过子类覆盖父类run()方法来达到需求;
*   第二种是实现线程的构造方法,构造方法传入一个Runnable参数,实现其run().
*
* 为什么大多数人都是使用第二种方法,而不是第一种?
*   第二种方法更符合面向对象的思想 ;第二种方法把线程中运行的代码放到了一个Runnable对象中,
*   固更加体现面向对象的思维;固使用第二种的方法比较普遍,更自然
*/

//三、线程3;以下代码使用的是Thread中的run方法,而不是Runnable中的run方法
/*
* 原因:
*   如果不覆盖父类的run方法就以父类的run方法为主,如果覆盖了就以子类覆盖的run方法为主;
*   父类的构造方法回去找Runnable中的run方法,所以这里的runnable不会执行
*/
new Thread(new Runnable(){
@Override
public void run() {
while(true){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread3--Runnable:"+Thread.currentThread().getName());
}
}
}){
@Override
public void run() {
while(true){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread3--Thread:"+Thread.currentThread().getName());
}
}
}.start();
}

/*
*  单线程比多线程快,性能更低;因为多线程之间的切换也要费时间,cpu只有一个
*  比如:
*      1、做馒头,我在一个桌子做馒头比在三个桌子做馒头快;看起来三个桌子都在产生馒头,
*    但你在这三个桌子间来回走动也费时间;
*      2、下载东西的时候为什么下载多个比下载一个快,这不是计算机本身加速了,
*    而是服务器给你分了其他人的带宽,简单的说就是你抢了别人的网速;
*      3、从u盘上把电脑上拷东西,考一个文件夹要不比分别考改文件下的子文件夹快。
*/
}
3.定时器案例分析及知识点应用
package com.itcast.family;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

/*
* 定时器Timer的使用
*/
public class TraditionalTimer {

//将其声明在此处是因为,内部类和方法内部不能声明静态变量
private static int count = 0;
public static void main(String[] args) {

/*
* Timer:定时器schedule:调度Task:任务
*/

/*
* 1.一个简单的连环炸弹定时器,初步 new Timer().schedule(new TimerTask() {
*
* @Override public void run() { System.out.println("bombing!"); } },
* 6000, 3000); //用线程是为了显示休眠时间,隔1秒输出一个时间秒 while(true){
* System.out.println(new Date().getSeconds()); try {
* Thread.sleep(1000); } catch (InterruptedException e) {
* e.printStackTrace(); } }
*/

/*
* 2.制造不同间隔交替执行的定时器,这是引出下面知识点的引子
* new Timer().schedule(new TimerTask() {

@Override
public void run() {
System.out.println("bombing!");
new Timer().schedule(
* new TimerTask() {
*
* @Override public void run() {
* System.out.println("bombing!"); } }
*
* 内部再嵌套Timer的运行结果:33 34 35 36 37 38
* bombing! 39 40 bombing! 41 bombing! 42 43
* bombing! 44
this
* 使用this代替再次Timer类放入运行结果:
* 52 53 54 55 56 57 bombing! 58
* Exception in thread "Timer-0"
* java.lang.IllegalStateException:
* Task already scheduled or
* cancelled
*   分析:会出现定时器无法再调度的结果,因为这是匿名内部类
*   只能执行一次,不能循环执行
, 2000);
}
}, 6000, 3000);
// 用线程是为了显示休眠时间,隔1秒输出一个时间秒
while (true) {
System.out.println(new Date().getSeconds());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}*/

//3.优化交替执行定时器代码:比如:一个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) {
System.out.println(new Date().getSeconds());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐