《Java编程那点事儿》读书笔记(七)——多线程
1.继承Thread类
通过编写新的类继承Thread类可以实现多线程,其中线程的代码必须书写在run方法内部或者在run方法内部进行调用。
public class NewThread extends Thread {
private int ThreadNum;
public NewThread(int ThreadNum){
this.ThreadNum = ThreadNum;
}
public void run(){
try{
for(int i = 0;i < 10;i ++){
Thread.sleep(1000);
System.out.println("running Thread"+ThreadNum+":"+i);
}
}catch(Exception e){
}
}
}
上述代码定义了新线程NewThread,并在run中实现输出十个数的功能。用以下代码在main函数中调用:
NewThread nt = new NewThread(1);
nt.start(); NewThread nt2 = new NewThread(2);
nt2.start();
得到的结果如下:
running Thread1:0
running Thread2:0
running Thread1:1
running Thread2:1
running Thread1:2
running Thread2:2
running Thread1:3
running Thread2:3
running Thread1:4
running Thread2:4
running Thread1:5
running Thread2:5
running Thread1:6
running Thread2:6
running Thread1:7
running Thread2:7
running Thread1:8
running Thread2:8
running Thread1:9
running Thread2:9
可以看到启动的两个线程并行运行。
2.实现Runnable接口(Java.lang.Runnable)
public class MyRunnable implements Runnable {
private int ThreadNum;
public MyRunnable(int ThreadNum){
this.ThreadNum = ThreadNum;
}
public void run(){
try{
for(int i = 0;i < 10;i ++){
Thread.sleep(1000);
System.out.println("running Thread"+ThreadNum+":"+i);
}
}catch(Exception e){
}
}
}
在main中调用接口:
MyRunnable mr = new MyRunnable(1);
Thread t = new Thread(mr); MyRunnable mr2 = new MyRunnable(2);
Thread t2 = new Thread(mr2); t.start();
t2.start();
3.Timer & TimerTask组合实现多线程
public class TimerAndTimerTask extends TimerTask{
private String s;
public TimerAndTimerTask(String s){
this.s = s;
}
public void run(){
try{
for(int i = 0;i < 10;i ++){
Thread.sleep(1000);
System.out.println("running Thread"+s+":"+i);
}
}catch(Exception e){
}
}
}
在main函数中创建线程代码如下:
Timer t = new Timer();
Timer t2 = new Timer(); TimerAndTimerTask tatt = new TimerAndTimerTask("1");
TimerAndTimerTask tatt2 = new TimerAndTimerTask("2"); t.schedule(tatt, 0);
t2.schedule(tatt2, 0);
上述代码中的要用两个Timer启动不同的线程,它们才能同时运行。如果只用一个Timer,则一次只能启动一个线程。
上述中的schedule方法一共有四种多态:
public void schedule(TimeTask task, Date time) //在2009年10月1日10点0分0秒启动该线程或超过该时间也启动线程
Date d = new Date(2009-1900,10-1,1,10,0,0);
t.schedule(task,d);
public void schedule(TimerTask task,Date firstTime,long period) //到达或者超过2009年10月1日10点时候每隔20000ms就启动一次线程,这种方式会重复触发线程
Date d = new Date(2009-1900,10-1,1,10,0,0);
t.schedule(task,d,20000);
public void schedule(TimerTask task,long delay) //执行启动代码1000ms后启动线程
t.schedule(task,1000);
//在delay ms后启动线程,并且每隔period ms启动一次
public void schedule(TimerTask task,long delay,long period)
在eclipse里面试了一下最后一种,会不断的输出0~9这10个数,因为用的Timer只有一个,但是每过1s就触发一次线程,所以不停的有线程需要执行。
4.互斥
synchronized,修饰方法或代码块,表示如果两个或者以上的线程同时执行该代码段时,如果一个线程已经开始执行该代码段,则另外一个线程必须等待这个线程执行完这段代码后才能执行。
public class Toilet {
public synchronized void enter(String name){
System.out.println(name+" enters the toilet!");
try{
Thread.sleep(2000);
}catch(Exception e){}
System.out.println(name + " has left the toilet!");
}
}
public class Human extends Thread{
private Toilet t;
private String s;
public Human(String s,Toilet t){
this.s = s;
this.t = t;
start();
}
public void run(){
t.enter(s);
}
}
在main中创建Human线程的代码如下,一共创建了三个Human线程:
Toilet t = new Toilet();
Human t1 = new Human("Ann", t);
Human t2 = new Human("Jeff", t);
Human t3 = new Human("Joe", t);
在上述Toilet类中有一段互斥的代码,输出当前进入厕所的人,并且在1s后离开。
在类Human中,在构造函数里面开启进程,所以每当new一个Human类就相当于开启了一个线程,但是会不会立即执行run函数要看系统中是否已经有在跑的Human线程,因为run函数里面调用了Toilet类中的enter函数,这个函数是互斥的,一次只能有一个线程执行。
程序两次执行的结果如下:
Jeff enters the toilet!
Jeff has left the toilet!
Joe enters the toilet!
Joe has left the toilet!
Ann enters the toilet!
Ann has left the toilet!
Ann enters the toilet!
Ann has left the toilet!
Jeff enters the toilet!
Jeff has left the toilet!
Joe enters the toilet!
Joe has left the toilet!
可以看到,线程执行的顺序并不是固定的,但是同一时刻一定只有一个线程可以执行enter这段代码。
5.同步
主要涉及两个函数
wait():使调用该方法的线程进入休眠
notify():使调用该方法的线程被唤醒
6.线程优先级
MAX_PRIORITY //最高优先级
NORM_PRIORITY //普通(默认)优先级
MIN_PRIORITY //最低优先级
如果上述main函数中通过调用MyRunnable类实现多线程的main函数中的程序改为如下:
MyRunnable mr = new MyRunnable(1);
Thread t = new Thread(mr);
t.setPriority(Thread.MIN_PRIORITY); MyRunnable mr2 = new MyRunnable(2);
Thread t2 = new Thread(mr2);
t2.setPriority(Thread.NORM_PRIORITY); MyRunnable mr3 = new MyRunnable(3);
Thread t3 = new Thread(mr3);
t3.setPriority(Thread.MAX_PRIORITY); t.start();
t2.start();
t3.start();
但是我没有得到书上的结果,大部分情况下是线程3先执行,但有时候也会出现线程2先执行的情况,某次执行的结果如下:
running Thread3:0
running Thread1:0
running Thread2:0
running Thread3:1
running Thread2:1
running Thread1:1
running Thread3:2
running Thread1:2
running Thread2:2
running Thread3:3
running Thread1:3
running Thread2:3
running Thread3:4
running Thread1:4
running Thread2:4
running Thread3:5
running Thread1:5
running Thread2:5
running Thread3:6
running Thread1:6
running Thread2:6
running Thread3:7
running Thread1:7
running Thread2:7
running Thread3:8
running Thread1:8
running Thread2:8
running Thread3:9
running Thread1:9
running Thread2:9
《Java编程那点事儿》读书笔记(七)——多线程的更多相关文章
- 《Java并发编程的艺术》读书笔记:二、Java并发机制的底层实现原理
二.Java并发机制底层实现原理 这里是我的<Java并发编程的艺术>读书笔记的第二篇,对前文有兴趣的朋友可以去这里看第一篇:一.并发编程的目的与挑战 有兴趣讨论的朋友可以给我留言! 1. ...
- 《深入了解java虚拟机》高效并发读书笔记——Java内存模型,线程,线程安全 与锁优化
<深入了解java虚拟机>高效并发读书笔记--Java内存模型,线程,线程安全 与锁优化 本文主要参考<深入了解java虚拟机>高效并发章节 关于锁升级,偏向锁,轻量级锁参考& ...
- <<Java RESTful Web Service实战>> 读书笔记
<<Java RESTful Web Service实战>> 读书笔记 第一章 JAX-RS2.0入门 REST (Representational State ransf ...
- 《Java并发编程的艺术》读书笔记:一、并发编程的目的与挑战
发现自己有很多读书笔记了,但是一直都是自己闷头背,没有输出,突然想起还有博客圆这么个好平台给我留着位置,可不能荒废了. 此文读的书是<Jvava并发编程的艺术>,方腾飞等著,非常经典的一本 ...
- 《Effective Java中文版第二版》读书笔记
说明 这里是阅读<Effective Java中文版第二版>的读书笔记,这里会记录一些个人感觉稍微有些重要的内容,方便以后查阅,可能会因为个人实力原因导致理解有误,若有发现欢迎指出.一些个 ...
- 《深入分析Java Web技术内幕》读书笔记之JVM内存管理
今天看JVM的过程中收获颇丰,但一想到这些学习心得将来可能被遗忘,便一阵恐慌,自觉得以后要开始坚持做读书笔记了. 操作系统层面的内存管理 物理内存是一切内存管理的基础,Java中使用的内存和应用程序的 ...
- MDX Step by Step 读书笔记(七) - Performing Aggregation 聚合函数之 Max, Min, Count , DistinctCount 以及其它 TopCount, Generate
MDX 中最大值和最小值 MDX 中最大值和最小值函数的语法和之前看到的 Sum 以及 Aggregate 等聚合函数基本上是一样的: Max( {Set} [, Expression]) Min( ...
- 《Java编程那点事儿》读书笔记(一)——基本数据结构
觉得自己记忆力很烂的样子,读书不做笔记就好像没读一样,所以决定以后读技术类的书籍,都要做好笔记. 1.IP地址和域名:如果把IP地址类比成身份证号的话,域名就是持证人的名字. 2.端口:规定一个 设备 ...
- 《Java编程那点事儿》读书笔记(五)——System,Integer,Calendar,Random和容器
System 1)arraycopy int[] a = {1.2.3.4}; int[] b = new int[5]; System.arraycopy(a,1,b,3,2); //把数组a中从下 ...
随机推荐
- Centos6.5以下Samba服务配置
一.简介 Samba是一个能让Linux系统应用Microsoft网络通讯协议的软件,而SMB是Server Message Block的缩写,即为服务器消息块 ,SMB主要是作为Microsoft的 ...
- MySQL高可用读写分离方案预研
目前公司有需求做MySQL高可用读写分离,网上搜集了不少方案,都不尽人意,下面是我结合现有组件拼凑的实现方案,亲测已满足要求,希望各位多提建议 :) 一. 网上方案整理(搜集地址不详...) 1 ...
- VS2012配置Lua环境
1.VS2012配置BabeLua插件 2.VS2012配置Lua 1.VS2012配置BabeLua插件 BabeLua插件简介: 安装方法: 关闭VS2012后直接安装BabeLua插件. 下载地 ...
- 简述负载均衡&CDN技术
曾经见到知乎上有人问“为什么像facebook这类的网站需要上千个工程师维护?”,下面的回答多种多样,但总结起来就是:一个高性能的web系统需要从无数个角度去考虑他,大到服务器的布局,小到软件中某个文 ...
- TEST ON 平安夜
1.前言 = = 感觉自己其实没发过关于考试的博客过... 今天是一个平安的夜晚,漆黑的夜被霓虹划分成网络,很适合发题. 2.num9九数码问题 传统8数码改一下...只询问一个状态,所以很容易搞,正 ...
- 【BZOJ】【1269】【AHOI2006】文本编辑器editor
Splay Splay序列维护的模板题了……为了便于处理边界情况,我们可以先插入两个空格当作最左端和最右端,然后……其实本题主要考察的就是Build.splay和Findkth这三个操作,我们可以实现 ...
- iNode for linux install
http://wenku.baidu.com/link?url=953T6GZCnaBzwr4YqPFUT4oOyYr4wyOnXlCLO1OUYZkaJWh2fTs634SM7ZpYiTKkpmYX ...
- winform 按顺序连续打印多个PDF文件
关于PDF打印的问题,前面有篇文章(点这里查看)也叙述过,今天来谈谈另外一种方法 其实方法很简单,因为需要把多个PDF文档按顺序连续打印,为此我们为什么不把要打印的pdf文档按顺序合并成一个PDF打印 ...
- openSSL漏洞原理及安全加固
2014年4月8日晚,互联网爆出了又一重量级安全漏洞,即CVE-2014-0160,通俗来讲就是OpenSSL出现了安全漏洞. 说 这个漏洞前,先介绍一下OpenSSL,OpenSSL是一个强大的安全 ...
- Hello world,Hello 2015,Bye 2014
序 在我写下“在”这个字的时候已经是2014-12-31 19:59,14年最后一天了,总觉得不写点东西祭奠一下那些被自己虐死的脑细胞,心里就不舒服. 那就从生活,工作,学习三个方面,总结一下吧. 生 ...