1.1什么是多线程编程

  多线程编程就是以线程为基本抽象单位的一种编程范式,和面向对象编程是可以相容的,事实上Java平台中的一个线程就是一个对象。多线程编程不是线程越多越好,就像“和尚挑水”的故事一样。

1.2为什么使用多线程

  提高程序运行效率。

1.3线程的创建、启动和运行

  java.lang.Thread就是java平台对线程的实现。Thread类的两个常用构造器是:Thread()和Thread(Runnable target)。1.使用第一种构造器。创建Thread类的实现子类,即继承Thread类的类。2.使用第二种构造器。创建Runnable接口的实例,即实现Runnable接口的类。

  1.3.1 继承Thread类

 public class demo{
public static void main(String[] args) {
Thread thread = new myDemo(); // 创建
thread.start();  //启动
System.err.println("thread1"+Thread.currentThread().getName()); } class myDemo extends Thread{ @Override
public void run() { // 运行
System.err.println("thread2"+Thread.currentThread().getName());
}
}
}

  1.3.2实现Runnable接口

 public class demo{

     public static void main(String[] args) {
Thread thread = new Thread(new myDemo()); // 创建
thread.start(); // 启动
System.err.println("thread1"+Thread.currentThread().getName()); } class myDemo implements Runnable{ @Override
public void run() { // 运行
System.err.println("thread2"+Thread.currentThread().getName());
}
} }

  1.3.3 注意

    1.线程属于“一次性用品”,不能多次调用同一线程的start方法,否则抛出 java.lang.IllegalThreadStateException异常

 1 public class demo{
2
3 public static void main(String[] args) {
4 Thread thread = new Thread(new myDemo()); // 创建
5 thread.start(); // 启动
thread.start(); // 启动
thread.start(); // 启动
6 System.err.println("thread1"+Thread.currentThread().getName());
7
8 }
9
10 class myDemo implements Runnable{
11
12 @Override
13 public void run() { // 运行
14 System.err.println("thread2"+Thread.currentThread().getName());
15 }
16 }
17
18 }

    2.不建议直接调用run方法,线程的run方法是由Java虚拟机直接调用的,如果在main方法中直接调用,运行是可以的,但是违背创建线程的初衷,线程的运行仍是mian线程。

1.4线程创建的区别

  1.4.1 创建一个线程与创建其他类型的Java对象的不同。

    创建线程对象比创建其他类型的对象成本要高。这是因为Java虚拟机会为每个线程分配调用栈(Call Stack)所需的内存空间,调用栈用于跟踪Java代码方法间的调用关系。第二是因为每个线程可能有一个内核线程与之对应,与java虚拟机的实现有关。

   1.4.2 线程两种创建方式的区别

    1.一种是基于继承的技术,创建Thread类的子类。另一种是基于组合的技术,以Runnable接口实例为构造器参数,创建Thread实例。基于组合相对于继承来说,类与类之间的耦合性更低,因此更灵活。

    2.从对象共享的角度来看,Runnable实例当作为多个线程的共享实例时,会出现竞态和线程安全问题

 public class demo {

     public static void main(String[] args) {
Thread t;
CountingTask ct = new CountingTask(); //创建Runnable实例
// 获取处理器个数
final int numberofProceesors = Runtime.getRuntime().availableProcessors();
System.err.println("获取处理器个数"+numberofProceesors);
for(int i=0; i<2*numberofProceesors; i++){
//直接创建线程
t = new Thread(ct); //实例被共享
t.start();
} for(int i=0;i<2*numberofProceesors; i++){
//以子类方式创建线程
t = new CountingThread();
t.start();
}
} static class Counter{
private int count = 0;
public void increment(){
count++;
}
public int value(){
return count;
}
} static class CountingTask implements Runnable{ private Counter counter = new Counter();
@Override
public void run() {
for(int i=0;i<10;i++){
doSomething();
counter.increment();
}
System.err.println("Runnable"+counter.value());
} }
static class CountingThread extends Thread{
private Counter counter = new Counter();
@Override
public void run() {
for(int i=0;i<10;i++){
doSomething();
counter.increment();
}
System.err.println("Thread"+counter.value());
}
}
static void doSomething(){
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

观察结果:

 获取处理器个数4
Runnable64
Runnable67
Runnable69
Runnable68
Runnable67
Runnable65
Runnable64
Runnable64
Thread10
Thread10
Thread10
Thread10
Thread10
Thread10
Thread10
Thread10

    3.从对象创建成本来看,创建一个线程实例要比创建一个普通的Runnable实例更昂贵。我的理解是new Thread( new Runnable()) = new Thread(),意思是一个线程实例(继承Thread)new Thread()的成本,等于实现Runnable接口方式下创建一个线程new Thread(参数)加 一个Runnable实例 ,类似于1+1=2,1<2的问题。

学习笔记《Java多线程编程实战指南》一的更多相关文章

  1. Java多线程编程实战指南(核心篇)读书笔记(五)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76730459冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  2. Java多线程编程实战指南(核心篇)读书笔记(四)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76690961冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  3. Java多线程编程实战指南(核心篇)读书笔记(三)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76686044冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  4. Java多线程编程实战指南(核心篇)读书笔记(二)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76651408冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  5. Java多线程编程实战指南(核心篇)读书笔记(一)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76422930冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  6. 《Java多线程编程实战指南(核心篇)》阅读笔记

    <Java多线程编程实战指南(核心篇)>阅读笔记 */--> <Java多线程编程实战指南(核心篇)>阅读笔记 Table of Contents 1. 线程概念 1.1 ...

  7. 学习笔记《Java多线程编程实战指南》三

    3.1串行.并发与并行 1.串行:一件事做完接着做下一件事. 2.并发:几件事情交替进行,统筹资源. 3.并行:几件事情同时进行,齐头并进,各自运行直到结束. 多线程编程的实质就是将任务处理方式由串行 ...

  8. 学习笔记《Java多线程编程实战指南》二

    2.1线程属性 属性 属性类型及用途  只读属性  注意事项 编号(id) long型,标识不同线程  是  不适合用作唯一标识 名称(name) String型,区分不同线程  否  设置名称有助于 ...

  9. Java多线程编程实战指南 设计模式 读书笔记

    线程设计模式在按其有助于解决的多线程编程相关的问题可粗略分类如下. 不使用锁的情况下保证线程安全: Immutable Object(不可变对象)模式.Thread Specific Storage( ...

随机推荐

  1. Linux虚拟机部署单机solr报错500解决方法之一

    HTTP Status 500 - {msg=SolrCore 'collection1' is not available due to init failure: Could not load c ...

  2. win10操作系统 安装nodejs报2503错误解决方法

    报该错误的原因是由于安装操作没有获得足够的管理权限导致. 在电脑左下角开始菜单[右键]选择"命令提示符(管理员)“ 敲入如下命令 msiexec /package 后面加你nodejs的本机 ...

  3. centOS6.0虚拟机ip配置

    1.首先使用虚拟机安装好centOS6.0系统 2.虚拟机网络配置:(选择桥接模式) 3. 第一步:首先关闭防火墙 1.将防火服务从启动列表移除 #chkconfig --del iptables # ...

  4. PXE自动装机

    PXE自动装机 一.搭建PXE远程安装服务器 PXE自动装机需要桌面模式 假如不是桌面模式安装的PXE需要安装桌面模式软件包 yum groupinstall "Desktop" ...

  5. linux 配置ftp服务器

    在Linux中搭建一个FTP服务器 [实现步骤] 1.检查安装vsftpd服务器 以root进入终端后(其他账户进入终端的可以用su root 输入密码后进入root 模式)之后,在终端命令窗口输入以 ...

  6. 第一模块 Python开发入门

    第一章 Python语法基础 变量的定义规范 一.声明变量 name = "Alex" 二.变量的定义规则 变量名只能是字母.数字或下划线的任意组合 变量名的第一个字符不能是数字 ...

  7. hive -e执行出现「cannot recognize input near '<EOF>' in select clause」问题

    问题现象 写了一个简单的shell脚本调用hive执行组装的sql,在执行时总是报cannot recognize input near '<EOF>' in select clause错 ...

  8. 20175120彭宇辰 《Java程序设计》第六周学习总结

    教材学习内容总结 第七章 一.内部类与外部类的关系 1.内部类可以使用外嵌类的成员变量和方法.2.类体中不可以声明类变量和类方法,外部类可以用内部类声明对象.3.内部类仅供外嵌类使用.4.类声明可以使 ...

  9. js中Array数组的属性和方法

    这是我自己整理出来的一些关于Array数组的属性和方法,即查即用. 1.Array.length属性:数组的项数组,始终返回0或者更大的值. 2.instanceof操作符:value instanc ...

  10. ccf-集合竞价-201412-3

    这道题数据量很小,所以用前缀和直接暴力解决了 首先将浮点数转换为整数; int_p=(int)(dou_p*100+0.5); 必须加一个eps,否则浮点数运算会有误差 然后从高到低枚举 #inclu ...