真的,身体这个东西一定要爱护好,难受的时候电脑都不想去碰,尤其是胃和肾。。。

这两天耽误了太多时间,今天好转了立刻学习,即刻不能耽误!、

话不多说,说正事:

1、多线程(理解)

  (1)多线程:一个应用程序有多条执行路径

      进程:正在执行的应用程序

      线程:进程的执行单元,或者说是执行路径

      单线程:一个应用程序只有一条执行路径

      多线程:一个应用程序有多条执行路径

    多进程的意义何在?

      提高CPU的使用率

    多线程的意义何在?

      提高应用程序的使用率

问题:

  一边玩游戏,一边听歌时同时进行的吗?

    不是,因为单CPU在某一个时间点上只能做一件事。

    而我们在玩游戏,或者听歌的时候,是CPU在做着程序间的高效切换让我们觉得是同时进行的。

  

  (2)Java程序的运行原理及JVM的启动是多线程的吗?

    A:Java命令去启动JVM,JVM会启动一个进程,该进程会启动一个主线程。

    B: JVM的启动是多线程的,因为它最低有两个线程启动了,主线程垃圾回收线程

      两个词汇:并行和并发

        并行是逻辑上同时发生,指在某一个时间段内同时运行多个程序。

        并发是物理上同时发生,指在某一个时间点同时运行多个程序。

      高并发:在某个时间点上很多人去访问一个(大数据)

  (3)多线程的实现方案

    A: 继承Thread类

      步骤:   

        1、自定义类MyThread继承Thread类

        2、MyThread类里面重写run()

        3、创建对象

        4、启动线程

MyThread类

 package com.wyh.Thread01;

 /**
* @author WYH
* @version 2019年11月22日 下午3:04:30
*/
public class MyThread extends Thread {
@Override
public void run() {
for(int x = 0; x<500;x++) {
System.out.println(x);
}
} }

测试类:

 package com.wyh.Thread01;

 /**
* @author WYH
* @version 2019年11月22日 下午3:05:18
*/
public class ThreadDemo01 {
public static void main(String[] args) {
MyThread my1 = new MyThread();
MyThread my2 = new MyThread(); my1.start();
my2.start();
} }

    B: 实现Runnable接口

        1、自定义类MyThread实现Runnable接口

        2、MyThread类里面重写run()

        3、创建对象

        4、创建Thread对象,把MyThread对象当作参数传入

        5、启动线程

Runnable类

 package com.wyh.Thread04;

 /**
* @author WYH
* @version 2019年11月22日 下午7:00:06
*/
public class MyRunnable implements Runnable { @Override
public void run() {
for (int x = 1; x <= 500; x++) {
System.out.println(Thread.currentThread().getName() + "--" + x);
} } }

测试类:

 package com.wyh.Thread04;

 /**
* @author WYH
* @version 2019年11月22日 下午7:01:07
*/
public class MyRunnableDemo {
public static void main(String[] args) {
MyRunnable my = new MyRunnable();
Thread t1 = new Thread(my,"王友虎");
Thread t2 = new Thread(my,"赵以浩"); t1.start();
t2.start(); } }

  (4)线程的调度和优先级问题

    A:线程的调度

      a:分时调度

      b:抢占式调度(Java采用的是该调度方式)

    B:获取和设置线程的优先级

      a:默认是5

      b:范围是1-10

  (5)线程的控制(常见方法)

    A:休眠线程(测试类在这不写,基本不变)

 package com.wyh.Thread03;

 import java.util.Date;

 /**
* @author WYH
* @version 2019年11月22日 下午3:04:30
*/
public class ThreadSleep extends Thread {
public ThreadSleep() {
super();
// TODO Auto-generated constructor stub
} public ThreadSleep(String name) {
super(name);
// TODO Auto-generated constructor stub
} @Override
public void run() {
for(int x = 0; x<500;x++) {
System.out.println(getName()+x+" 日期:"+new Date());
//睡眠1秒
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
} }

    B:加入线程(run方法类不变)

 package com.wyh.Thread03;

 /**
* @author WYH
* @version 2019年11月22日 下午3:05:18
*
* join 为了让某些线程执行完毕,才能执行其他的(线程加入)
*
*
*
*/
public class ThreadJoinDemo {
public static void main(String[] args) { ThreadPriority my1 = new ThreadPriority("王友虎");
ThreadPriority my2 = new ThreadPriority("李宏灿");
ThreadPriority my3 = new ThreadPriority("齐博源"); my1.start();
try {
my1.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} my2.start();
my3.start(); } }

    C:礼让线程(省略测试类代码)

 package com.wyh.Thread03;

 /**
* @author WYH
* @version 2019年11月22日 下午4:28:15
*/
public class ThreadYield extends Thread {
public ThreadYield() {
super();
// TODO Auto-generated constructor stub
} public ThreadYield(String name) {
super(name);
// TODO Auto-generated constructor stub
} @Override
public void run() {
for(int x = 0; x<200;x++) {
System.out.println(getName()+x);
Thread.yield();
}
}
}

    D:后台线程(省略继承类的代码)//注意!!!!必须在启动前声明

 package com.wyh.Thread03;

 /**
* @author WYH
* @version 2019年11月22日 下午4:42:16
*
* 守护线程
*
* 理解:坦克大战,黄绿坦克守护家,家没了,坦克也没了
*
*/
public class ThreadDeamonDemo {
public static void main(String[] args) {
ThreadDeamon td1 = new ThreadDeamon("关羽");
ThreadDeamon td2 = new ThreadDeamon("张飞"); //注意!!!!必须在启动前声明
td1.setDaemon(true);
td2.setDaemon(true); td1.start();
td2.start(); Thread.currentThread().setName("刘备");
for (int x = 0; x < 5; x++) {
System.out.println(Thread.currentThread().getName() + x);
}
} }

    E:终止线程(不推荐使用stop,而且该方法已经过时,推荐使用interrupt)

继承类:

 package com.wyh.Thread03;

 import java.util.Date;

 /**
* @author WYH
* @version 2019年11月22日 下午4:57:38
*/
public class ThreadStop extends Thread{
@Override
public void run() {
System.out.println("时间:"+new Date()); //睡眠10秒钟
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
System.err.println("睡眠被意外中止!!");
} System.out.println("时间:"+new Date()); }
}

测试类:

 package com.wyh.Thread03;

 /**
* @author WYH
* @version 2019年11月22日 下午5:00:21
*/
public class ThreadStopDemo {
public static void main(String[] args) {
ThreadStop ts = new ThreadStop();
ts.start(); try {
Thread.sleep(3000);
// ts.stop(); //不建议使用 因为后面的代码无法执行
ts.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
} } }

  (6)线程的生命周期(图解)

  (7)电影院卖票程序的实现

      A:继承Thread类

继承类:

 package com.wyh.Thread05;

 /**
* @author WYH
* @version 2019年11月22日 下午7:33:38
*/
public class SellTicket extends Thread {
private static int tickets = 100; @Override
public void run() {
while(true) {
if(tickets>0) {
System.out.println(getName()+"窗口正在售卖第"+(tickets--)+"张票。。");
} }
}
}

测试类:

 package com.wyh.Thread05;

 /**
* @author WYH
* @version 2019年11月22日 下午7:36:19
*/
public class TicketDemo {
public static void main(String[] args) {
//先创建多个线程
SellTicket st1 = new SellTicket();
SellTicket st2 = new SellTicket();
SellTicket st3 = new SellTicket(); //给多个线程起名字’
st1.setName("窗口1");
st2.setName("窗口2");
st3.setName("窗口3"); st1.start();
st2.start();
st3.start(); } }

      B:实现Runnable接口

实现Runnable接口类:

 package com.wyh.Thread05;

 /**
* @author WYH
* @version 2019年11月22日 下午7:42:37
*/
public class SellTicket_Runnable implements Runnable {
private int tickets = 100; @Override
public void run() {
while(true) {
if(tickets>0) {
System.out.println(Thread.currentThread().getName()+"窗口正在售卖第"+(tickets--)+"张票。。");
}
} } }

测试类:

 package com.wyh.Thread05;

 /**
* @author WYH
* @version 2019年11月22日 下午7:43:48
*/
public class SellTicket_RunnableDemo {
public static void main(String[] args) {
SellTicket_Runnable sr = new SellTicket_Runnable(); Thread t1 = new Thread(sr,"窗口1");
Thread t2 = new Thread(sr,"窗口2");
Thread t3 = new Thread(sr,"窗口3"); t1.start();
t2.start();
t3.start(); } }

  (8)电影院卖票程序出的问题

    A:为了更加符合真实场景,加入了休眠100毫秒。

    B:买票问题

      a:同票被多次出售

      b:出现0票和负数票

  (9)多线程安全问题的原因(也是我们以后判断一个程序是否有安全问题的依据)

    A:是否有多线程环境

    B:是否有共享数据

    C:是否有多条语句操作共享数据

  (10)同步解决线程安全问题(以解决上面售票的为例解决)

    A:同步代码块

        synchronized(对象){

          需要被同步的代码;

        }

      这里的对象可以是任意对象(充当锁的作用,下面也是相同作用)

实现接口类:(测试类代码不变)

 package com.wyh.Thread06_tickets;

 /**
* @author WYH
* @version 2019年11月22日 下午7:42:37
*/
public class SellTicket_Runnable implements Runnable {
private int tickets = 300;
private Object obj = new Object(); //如同一把锁 多个线程共用一把锁,把对共享数据的操作包起来 @Override
public void run() {
while(true) {
synchronized(obj) {
if(tickets>0) {
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"窗口正在售卖第"+(tickets--)+"张票。。");
}
} } } }

    B:同步方法

      把同步放在方法上。

      这里的锁对象是 this

实现接口类:(测试类代码不变)

 package com.wyh.Thread07_tickets2_同步方法静态;

 /**
* @author WYH
* @version 2019年11月22日 下午7:42:37
*/
public class SellTicket_Runnable implements Runnable {
private int tickets = 300;
private int x = 0; //用obj对象做锁
private Object obj = new Object(); //如同一把锁 多个线程共用一把锁,把对共享数据的操作包起来 @Override
public void run() {
if(x%2==0) {
while(true) {
synchronized(this) {
if(tickets>0) {
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"窗口正在售卖第"+(tickets--)+"张票。。");
}
} }
}else {
synchronize();
} } private synchronized void synchronize() {
while(true) {
if(tickets>0) {
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"窗口正在售卖第"+(tickets--)+"张票。。");
} } }
}

    C:静态同步方法

       把同步加在方法上。

       这里的锁对象是当前类的字节码文件对象(反射)

 package com.wyh.Thread07_tickets2_同步方法静态;

 /**
* @author WYH
* @version 2019年11月22日 下午7:42:37
*/
public class SellTicket_Runnable2 implements Runnable {
private static int tickets = 300;
private int x = 0; @Override
public void run() {
if(x%2==0) {
while(true) {
synchronized(SellTicket_Runnable2.class) {
if(tickets>0) {
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"窗口正在售卖第"+(tickets--)+"张票。。");
}
} }
}else {
synchronize();
} } private synchronized static void synchronize() {
while(true) {
if(tickets>0) {
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"窗口正在售卖第"+(tickets--)+"张票。。");
} } }
}

·  (11)回顾以前的线程安全的类

      A:StringBuffer

      B:Vector

      C:HashTable

      D:如何把一个线程不安全的集合变成一个线程安全的集合类

          用Collections 工具类的方法即可。

以List集合为例:其他集合创建方法类似,具体看API

 package Collections保证线程安全的;

 import java.util.ArrayList;
import java.util.Collections;
import java.util.List; /**
* @author WYH
* @version 2019年11月22日 下午9:10:58
*/
public class Demo {
public static void main(String[] args) {
//以List集合为例
//以前的我们是这么做的
List<String> list1 = new ArrayList<String>(); //这么创建的List是不安全的 //Collections 工具类提供的方法 同步安全的
List<String> list2 = Collections.synchronizedList(new ArrayList<String>()); list2.add("1");
list2.add("2"); for(String s : list2) {
System.out.println(s);
}
} }

线程中需要注意的问题:

  1、Thread中start()方法的功能就是创建一个新的线程,并自动调用该线程的run()方法,直接调用run()方法是不会创建一个新的线程的,直接调用相当于调用一个普通方法。

  2、执行一个线程实际就是执行该线程run方法中的代码

  3、一个Thread对象只能代表一个线程。

      一个Thread对象不能调用两次start()方法,否则会抛出java.lang.IllegalThreadStateException异常

大数据之路week03--day05(线程 I)的更多相关文章

  1. 大数据之路week03--day05(线程 II)

    今天,咱们就把线程给完完全全的结束掉,但是不是说,就已经覆盖了全部的知识点,可以说是线程的常见的问题及所含知识基本都包含. 1.多线程(理解) (1)JDK5以后的针对线程的锁定操作和释放操作 Loc ...

  2. 大数据之路week01--自学之集合_1(Collection)

    经过我个人的调查,发现,在今后的大数据道路上,集合.线程.网络编程变得尤为重要,为什么? 因为大数据大数据,我们必然要对数据进行处理,而这些数据往往是以集合形式存放,掌握对集合的操作非常重要. 在学习 ...

  3. 大数据之路week07--day03(Hadoop深入理解,JAVA代码编写WordCount程序,以及扩展升级)

    什么是MapReduce 你想数出一摞牌中有多少张黑桃.直观方式是一张一张检查并且数出有多少张是黑桃. MapReduce方法则是: 1.给在座的所有玩家中分配这摞牌 2.让每个玩家数自己手中的牌有几 ...

  4. 大数据之路week04--day06(I/O流阶段一 之异常)

    从这节开始,进入对I/O流的系统学习,I/O流在往后大数据的学习道路上尤为重要!!!极为重要,必须要提起重视,它与集合,多线程,网络编程,可以说在往后学习或者是工作上,起到一个基石的作用,没了地基,房 ...

  5. 大数据之路week04--day03(网络编程)

    哎,怎么感觉自己变得懒了起来,更新博客的频率变得慢了起来,可能是因为最近得知识开始变得杂变得难了起来,之前在上课的时候,也没有好好听这一方面的知识,所以,现在可以说是在学的新的知识,要先去把新的知识思 ...

  6. C#码农的大数据之路 - 使用C#编写MR作业

    系列目录 写在前面 从Hadoop出现至今,大数据几乎就是Java平台专属一般.虽然Hadoop或Spark也提供了接口可以与其他语言一起使用,但作为基于JVM运行的框架,Java系语言有着天生优势. ...

  7. 胖子哥的大数据之路(11)-我看Intel&&Cloudera的合作

    一.引言 5月8日,作为受邀嘉宾,参加了Intel与Cloudera在北京中国大饭店新闻发布会,两家公司宣布战略合作,该消息成为继Intel宣布放弃大数据平台之后的另外一个热点新闻.对于Intel的放 ...

  8. 胖子哥的大数据之路(10)- 基于Hive构建数据仓库实例

    一.引言 基于Hive+Hadoop模式构建数据仓库,是大数据时代的一个不错的选择,本文以郑商所每日交易行情数据为案例,探讨数据Hive数据导入的操作实例. 二.源数据-每日行情数据 三.建表脚本 C ...

  9. 胖子哥的大数据之路(9)-数据仓库金融行业数据逻辑模型FS-LDM

    引言: 大数据不是海市蜃楼,万丈高楼平地起只是意淫,大数据发展还要从点滴做起,基于大数据构建国家级.行业级数据中心的项目会越来越多,大数据只是技术,而非解决方案,同样面临数据组织模式,数据逻辑模式的问 ...

随机推荐

  1. Andrew Ng机器学习课程16

    Andrew Ng机器学习课程16 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:主要介绍了ICA算法,并利用最大似然估计和随机梯度上升算法进行求解, ...

  2. 最新 东方网java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.东方网等10家互联网公司的校招Offer,因为某些自身原因最终选择了东方网.6.7月主要是做系统复习.项目复盘.LeetCo ...

  3. Shiro加盐加密

    接本人的上篇文章<Shiro认证.角色.权限>,这篇文章我们来学习shiro的加盐加密实现 自定义Realm: package com.czhappy.realm; import org. ...

  4. 使用idea上传项目初始化版本到coding

    1.在coding创建项目 2.使用idea命令控制台初始化本地仓库 3.将代码提交到本地仓库,git add . 或者 git add <filename> 4.将本地仓库文件推送到co ...

  5. Python 实现把两个排好序的的列表合并成一个排序列表

    列表是升序的 # -*- coding: utf-8 -*- # 合并两个排序的数组 def merge_list(a, b): if not a: return b if not b: return ...

  6. Navicat通过跳板机连接MySQL(2层跳转)

      情景描述,公司开发数据库部署在内网,而且这个开发数据库有连接需要有IP验证,就是只能在内网的某个IP才能连接,所以每次连接都会先连接外网能访问的跳板机,在从跳板机上ssh到内网上的A机器,在从A机 ...

  7. 数据结构 -- 哈希表(hash table)

    简介   哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函 ...

  8. Word 双栏排版最后多一页空白页删不掉、左栏文字没写完就到右栏了

    1. 问题 问题:Word双栏排版,最后多一页空白页,删不掉.如图: 原因分析:删不掉是因为末尾文字处其实有个下一页分节符,只不过可能看不到. 如何清晰的看到? 视图 > 大纲,就可以看到了.如 ...

  9. php之简单算法

    选择排序 方式:先让第一位与其他位比较大小找到最小的数字,然后是第二位与除第一位的其他位比较大小找出第二位,依此类推 $arr = [2,45,12,67,33,5,23,132,46]; for ( ...

  10. pandas 索引笔记

    import pandas as pd import numpy as np s = pd.Series(np.random.rand(5), index=list('abcde')) # 创建序列, ...