------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

  如果一次只完成一个事情,还是比较容易实现的,但事实上很多事情都是同时执行的,java为了模拟这种状态,引入了线程机制。

当程序同时完成多个事情时,就是所谓的多线程程序。

  在一个时刻,单核的cpu只能运行一个程序。而我们看到的同时运行效果,只是cpu在多个进程间做着快速的随机切换动作。

  所以说多线程解决了多部分同时运行的问题,但是线程太多的话肯定会影响效率。

  首先老规矩一张图来展现我们本次要介绍的内容:

一、实现方式

实现线程的方式一共有两种---继承Thread类和实现Runnable接口。

1、继承Thread类。

a、定义类继承Thread。

b、复写Thread中的run方法。

c、创建定义类的实例对象。

d、调用start方法启动线程。

class TestThread extends Thread            // a、定义类继承Thread。
{
public void run() //b、复写Thread中的run方法。
{
for (int x = 0; x < 50 ;x++ )
{
System.out.println(Thread.currentThread().getName()+"......"+x);
}
}
} class Demo
{
public static void main(String[] args)
{
TestThread t1= new TestThread();//c、创建定义类的实例对象。
TestThread t2= new TestThread();
t1.start(); //d、调用start方法启动线程。
t2.start();
}
}

2、实现runnable接口

  a、定义类实现Runnable的接口。

b、覆盖Runnable接口中的run方法。

c、通过Thread类创建线程对象。

d、调用start方法启动线程。

class TestThread implements Runnable            //a、定义类实现Runnable的接口。
{
public void run() // b、覆盖Runnable接口中的run方法。
{
for (int x = 0; x < 50 ;x++ )
{
System.out.println(Thread.currentThread()+"++++++"+x);
}
}
}
class Demo
{
public static void main(String[] args)
{ TestThread d = new TestThread();
Thread t1 = new Thread(d);
Thread t2 = new Thread(d); //c、通过Thread类创建线程对象。
t1.start();      //d、调用start方法启动线程。
t2.start();
}
}

3、实现Runnable接口的优势

  实际开发中,我们经常使用第二种方式做多线程,它的优势在于

  a、避免了按照面向对象的思想将任务封装成对象。

  b、避免了java单继承的局限性。

二、线程的生命周期

线程具有生命周期,其各个生命周期的关系如下图。

三、线程安全

  实际开发中,使用多线程的情况有很多,比如火车站售票系统,当有多个线程做取票动作时,假设此时只有一张票,一线程将票售出,此时二线程完成了判断是否有票动作,并得出票数大于0结论。此时执行售票就会产生负数。

1、安全问题产生的原因

  a、多个线程在操纵共享数据

  b、操纵共享数据的代码有多条。

2、解决办法--同步

  将多条操作共享数据的线程代码封装起来,当有线程执行这些代码时候,其他线程不可参与。

  a、同步代码块

  

synchronized(obj)
{
  //需要同步的代码
}

  b、同步函数

public synchronized void show()
{
//需要同步的代码
}

3、同步函数和同步代码块的区别

  同步函数的锁是this

  同步代码块的锁是任意的(也可以是this)

  实际开发中建议用同步代码块。

4、同步的利弊

好处:解决了多线程的安全问题。

弊端:多个线程需要判断锁,较为消耗资源。

5、静态函数代码块

  如果同步函数被静态修饰后,使用的锁是什么呢?设计模式中的单例模式给大家展示。

//懒汉式
class Single
{
private static Single s = null; private Single(){} public static Single getInstance()
{
if(s == null)
{
synchronized(Single.class) //静态方法写---类名.class
{
if(s==null)
s = new Single();
}
}
return s;
}
}

四、线程间通信

线程间的通信其实就是多个线程共享同一个资源。

class  ResorceDemo
{
public static void main(String[] args)
{
Resorce r = new Resorce();
Input in = new Input(r);
Output out = new Output(r);
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
t1.start();
t2.start();
}
}
class Resorce //定义一个资源
{
String name;
String sex;
boolean flag = false;
} class Input implements Runnable
//写入资源
{
Resorce r;
Input(Resorce r)
{
this.r = r;
}
public void run()//复写run方法
{
int x = 0;//x相当于一个标志.
while (true)
{
synchronized(r)
{
if (r.flag == true)
{
try
{
r.wait();
}
catch (InterruptedException e)
{
} }
else
{
if (x==0)
{
r.name = "mike";
r.sex = "nan";
}
else
{
r.name = "傻妞";
r.sex = "妞妞妞妞i牛i牛ii牛";
}
r.flag = true;
r.notify();//唤醒
}
x = (x+1)%2;//x在0和1之间相互交替. }
}
}
}
class Output implements Runnable
//读取资源
{
Resorce r;
Output(Resorce r)
{
this.r = r;
}
public void run()
{
while (true)//无限循环
{
synchronized(r)
{
if (r.flag == false)
{
try
{
r.wait();
}
catch (InterruptedException e)
{
} }
else
{
System.out.println(r.name + "..."+r.sex);
r.flag = false;
r.notify();
} } }
}
}

五、常见操作方法

1,wait(): 让线程处于冻结状态,被wait的线程会被存储到线程池中。
2,notify():唤醒线程池中一个线程(任意).
3,notifyAll():唤醒线程池中的所有线程。
4,setPriority():设置优先级
5,yield():暂停当前线程,让其他线程执行。

当然,这些常见的操作方法在API中都可以查到,这不是我要说的重点,下面来对这些方法做一下比较。

(1)wait 和 sleep 区别?

  1,wait可以指定时间也可以不指定。    sleep必须指定时间。

  2,在同步中时,对cpu的执行权和锁的处理不同。  wait:释放执行权,释放锁。  sleep:释放执行权,不释放锁。

(2)wait(),notify(),notifyAll(),用来操作线程为什么定义在了Object类中?

a,这些方法存在与同步中。

b,使用这些方法时必须要标识所属的同步的锁。同一个锁上wait的线程,只可以被同一个锁上的notify唤醒。

c,锁可以是任意对象,所以任意对象调用的方法一定定义Object类中。

六、总结

多线程本身也是比较复杂的问题,要完全理解它还需要时间,所谓孰能生巧,这些知识还是要多看多练多去实践才能真正掌握。

黑马程序员----java基础:多线程的更多相关文章

  1. 黑马程序员 Java基础<九>---> 多线程

    ASP.Net+Android+IOS开发..Net培训.期待与您交流! 多线程 一.概述: 1.线程是什么 说到线程,我们就得先说说进程.所谓进程,就是一个正在执行(进行)中的程序,每一个进程执行都 ...

  2. 黑马程序员——JAVA基础之多线程的安全问题

    ------- android培训.java培训.期待与您交流! ---------- 导致多线程出现问题的一个特殊的状态:就绪.具备了执行资格,但是还没有获取资源. 导致安全问题的出现的原因: 1. ...

  3. 黑马程序员——JAVA基础之多线程的线程间通讯等

    ------- android培训.java培训.期待与您交流! ---------- 线程间通讯: 其实就是多个线程在操作同一个资源,但是动作不同. wait(); 在其他线程调用此对象的notif ...

  4. 黑马程序员----java基础笔记中(毕向东)

    <p>------<a href="http://www.itheima.com" target="blank">Java培训.Andr ...

  5. 黑马程序员Java基础班+就业班课程笔记全发布(持续更新)

    正在黑马学习,整理了一些课程知识点和比较重要的内容分享给大家,也是给自己拓宽一些视野,仅供大家交流学习,大家有什么更好的内容可以发给我 ,现有黑马教程2000G  QQ 1481135711 这是我总 ...

  6. 黑马程序员----java基础笔记上(毕向东)

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 笔记一共记录了毕向东的java基础的25天课程,分上.中.下 本片为上篇,涵盖前10天课程 1. ...

  7. 黑马程序员——JAVA基础之泛型和通配符

    ------- android培训.java培训.期待与您交流! ---------- 泛型:            JDK1.5版本以后出现新特性.用于解决安全问题,是一个类型安全机制. 泛型好处: ...

  8. 黑马程序员——JAVA基础之简述面向对象,类,变量,匿名对象

    ------- android培训.java培训.期待与您交流! ---------- 面向对象: 面向对象是相对面向过程而言 面向对象和面向过程都是一种思想 面向过程 强调的是功能行为 面向对象 将 ...

  9. 黑马程序员——JAVA基础之语法、命名规则

    ------- android培训.java培训.期待与您交流! ---------- 1.java语言组成:关键字,标识符,注释,常量和变量,运算符,语句,函数,数组. 2.java关键字:被Jav ...

随机推荐

  1. 2016/04/29 smarty模板 1, 初步 目标 : 变量 运算符 表达式 流程控制 函数

    ① 从配置文件中读取配置: 1,在模板页面加载配置文件 html页面 不是php页面 <{config_load file='fo.conf'}> 2,在需要用到配置的地方加 <{# ...

  2. lsblk df

    df(1) - Linux manual page http://man7.org/linux/man-pages/man1/df.1.html report file system disk spa ...

  3. 鉴权应用服务器 app客户端 web服务端 安全令牌(SecurityToken)、临时访问密钥(AccessKeyId, AccessKeySecret)

    设置EndPoint和凭证 移动终端是一个不受信任的环境,把AccessKeyId和AccessKeySecret直接保存在终端用来加签请求,存在极高的风险.建议只在测试时使用明文设置模式,业务应用推 ...

  4. 【Java报错】Message: 3 字节的 UTF-8 序列的字节 2 无效

    报错logs 2015-03-10 10:15:32,360 ERROR [qtp32195030-27] [InvokeAfterValve.java:55] - javax.xml.stream. ...

  5. HDU1087 Super Jumping! Jumping! Jumping! —— DP

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1087 Super Jumping! Jumping! Jumping! Time Limi ...

  6. silverlight漂亮的文件上传进度显示原理及示例

    silverlight漂亮的文件上传进度显示原理及示例 作者:chenxumi 出处:博客园  2009/11/27 13:37:11 阅读 1219  次 概述:在网站根目录web.config里配 ...

  7. I.MX6 MAC Address 导致的系统崩溃

    /**************************************************************************** * I.MX6 MAC Address 导致 ...

  8. Java-Runoob-高级教程-实例-数组:01. Java 实例 – 数组排序及元素查找

    ylbtech-Java-Runoob-高级教程-实例-数组:01. Java 实例 – 数组排序及元素查找 1.返回顶部 1. Java 实例 - 数组排序及元素查找  Java 实例 以下实例演示 ...

  9. 在linq语言中,不能准确按拼音排序(转)

    在项目中,利用OrderBy/OrderByDescending, ThenBy/ThenByDescending这4个方法排序时,发现了这样的问题:在本机测试,能正确按拼音排序:但是放上服务器是,就 ...

  10. PCB CAM自动化后台配置说明

    CAM自动化项目经历9个月时间里,在我们IT团队与工程部深入合作下,依据PCB各种场景定制特定功能,且这几个月里在不断的改进与迭代脚本功能,在此期间攻破了一个又一个难题,最终项目第一阶段已顺立上线运行 ...