一  引言 :

进程是一个正在执行中的程序,每个进程执行都有一个执行顺序,或执行路径;

线程是进程中的内容,是进程中独立的控制单元;

线程控制着进程的执行,或者是一个控制单元;

一个进程中至少有一个线程;

二  如何创建线程

1.第一种方式为:

将类声明为Thread的子类,该子类应重写Thread类的run方法

例如:


class TestChildThread extends Thread{@Overridepublic void run() {super.run();}
}

创建好子线程后,我们接下来启动使用它

class Test { public static void main(String[] args) {//创建线程TestChildThread d = new TestChildThread(); //启动d . start();}}

 2. 第二种方式是实现 Runnable接口,并重写Thread的run方法

class  RunnableDemo implements Runnable{@Overridepublic void run() {}
}class TestRunnableClass{public static void main(String[] args){RunnableDemo  runnableDemo  = new  RunnableDemo();Thread  t = new  Thread(runnableDemo);t . start();}
}

注:  1. 定义类实现Runable接口来创建线程

2. 覆盖 Runable 中run方法,将要执行的代码放入;

3. 通过 Thread 类建立线和对象

4.将 Runnable接口子类对象作为实际参数传递给Thread类的构造函数中

5.调用 Thread类的 start  方法 开户线程

注: 两种创建线程方式的区别:

实现方式的好处,了单继承的局限性

在定义线程时,建议使用实现类

继承Thread: 线程代码存放在Thread类的run方法中

实现Runable,线程将代码存放在接口的子类run方法中

3.注  :  在某一个时刻,只能有一个程序在运行;

在多线程中,有一个特性:随机执行;

d . run();是调用类Demo类中的run方法,而未启动线程

      4.为什么要重写run方法?

将自定义代码存储在run方法中,让线程运行;

例:

class ThreadDemos1 extends Thread
{public void run(){for(int x =0;x<10;x++){System.out.println(this.getName()+" " + x);}}
}//其中   this.getName  是获得线程的名称class ThreadDemos2 extends Thread
{ThreadDemos2(String name){super(name);}public void run(){for(int x =0;x<10;x++){System.out.println(this.getName()+" " + x);}}
}

建立测试类

public class TestDemo {public static void main(String[] args) {ThreadDemos1  d1 = new ThreadDemos1();d1.start();ThreadDemos2  d = new ThreadDemos2("one");d.start();}
}

三  多线程运行状态

阻塞状态

|

线程建立——(start())——运行————sleep()————冻结

|

stop

四  自定义线程名称:

** 线程都有自己的名称 : Thread-标号  ,,  标号是从0开始的;

**  获得线程名称的方法 : this.getName();     Thread.currentThread().getName()

**  可以在线程初始化始时对线程命名;

       1.在线程初始化时候对其命名

class Demoss extends Thread{public void run(){for(int x =0;x<10;x++){System.out.println(this.getName()+" " + x);}}}public class TestDemo {public static void main(String[] args) {Demoss  d1 = new Demoss("one");d1.start();}
}

2. 可以使用构造函数对其重命名;

class Demos extends Thread{Demos(String name){super(name);}public void run(){for(int x =0;x<10;x++){System.out.println(this.getName()+" " + x);}}}public class TestDemo {public static void main(String[] args) {Demos  d1 = new Demos("one");d1.start();}
}

五 多线程的安全问题

1.同步 代码块

java对于多线程的安全问题,提供了专业的解决方式,就是  使用同步代码块,

结构

   synchronized(对象){被同步的代码}

例如一个售票例子

总共1000张票   四个售票机

package test;public class TestDeoo {public static void main(String[] args) {Ticket  t = new Ticket();Thread  t1 = new Thread(t);Thread  t2 = new Thread(t);Thread  t3 = new Thread(t);Thread  t4 = new Thread(t);t1.start();t2.start();t3.start();t4.start();}}class Ticket implements Runnable{private int tick=1000;Object obj = new Object();public void run(){while(true){synchronized(obj){if(tick>0){"                                 try{Thread.sleep(10);}catch(Exception e){ };}      <pre name="code" class="java">

System.out.println(Thread.currentThread().getName()+"sale"+tick--); } } }}

     2.同步代码块原理:

例如有两个线程,当线程0获得CPU的执行权后,会读到synchronized代码块, 判断,然后会获得进入许可,继续执行下面的代码,随后synchronized 关闭入口,读到  stop时,线程结束,此时入口开放,等待下一线程的进入执行。。。。。。。。。。

3.使用同步代码块的前提

<1> 必须有两个或者两个以上的线程

<2> 必须是多个线程使用同一个锁

     4.同步代码块的好处

解决了线程的安全问题

      5.同步代码块的弊端

多个线程要判断锁,较为消耗资源

六 同步函数

public class StringDemo {public static void main(String[] args) {Cuss c = new Cuss();Thread t = new Thread(c);Thread t2 = new Thread(c);t.start();t2.start();}
}class Bank {private int sum;Object obj = new Object();public void add(int x) {synchronized (obj) {sum = sum + x;try {Thread.sleep(10);} catch (Exception e) {}System.out.println("sum " + sum);}}
}class Cuss implements Runnable {private Bank b = new Bank();public void run() {for (int x = 0; x < 3; x++) {b.add(100);System.out.println(Thread.currentThread().getName());}}
}

使用同步函数形式来写出上述问题

class Banks {private int sum;Object obj = new Object();public synchronized void add(int x) {sum = sum + x;try {Thread.sleep(10);} catch (Exception e) {}System.out.println("sum " + sum);}
}class Cuss implements Runnable{private Banks b = new Banks();public void run() {for (int x = 0; x < 3; x++) {b.add(100);System.out.println(Thread.currentThread().getName());}}
}public class stringDemo {public static void main(String[] args) {Cuss c = new Cuss();Thread t = new Thread(c);Thread t2 = new Thread(c);t.start();t2.start();}
}

七  单例设计模式

 1.   饿汉式

class Single {private static final Single s = new Singles();private Single() {}public static Single getInstanceP{return s;}
}

2. 懒汉式

class Single {private static Single s = null;private Single() {}public static Single getInstance() {if (s == null) {synchronized (Single.class) {if (s == null) {s = new Single();}}}return s;}
}

线程间的通讯

线程间的的通讯,其实就是多个线程在操作同一个资源;但是操作的动作不同的资源

新建一个资源:

class Res
{String name;String sex; }

创建一个输入线程类:   输入与输出线程要操作同一个资源

class Input implements Runnable
{Res  r;Input(Res r){this.r=r;}public void run(){boolean b =true;while(true){if(b){r.name="lishi";r.sex="man";b = false;}else{r.name="李四";r.sex="男";b = true;}}}
}

新建一个输出线程:  输入线程与输出线程操作的是同一个资源

class Output implements Runnable
{Res  r;Output(Res r){this.r=r;}public void run(){while(true){System.out.println(r.name);}}
}

新建一个测试类

 public class TestDemo {public static void main(String[] args) {Res  r = new Res();Input in = new Input(r);Output out = new Output(r);Thread t = new Thread(in );Thread tl = new Thread(out);t.start();tl.start();}
}

这个程序的输出结果应该为  lishi  man

李四   男

。。。。。

测试一下,会出现乱码现象,如果要修改安全问题,就应该使用同步代码块

class Res
{String name;String sex; }
class Input implements Runnable
{Res  r;Input(Res r){this.r=r;}public void run(){boolean b =true;while(true){synchronized(r){if(b){r.name="lishi";r.sex="man";b = false;}else{r.name="李四";r.sex="男";b = true;}}}}
}
class Output implements Runnable
{Res  r;Output(Res r){this.r=r;}public void run(){synchronized(r){while(true){System.out.println(r.name+"  "+r.sex);}}}
}

这样的话就解决了线程间的安全问题了

线程间的等待唤醒机制

新建一个资源

class Res
{String name;String sex; boolean bo =  false;}
class Input implements Runnable
{Res  r;Input(Res r){this.r=r;}public void run(){boolean b =true;while(true){synchronized(r){if(r.bo)try{r.wait();}catch(Exception e){}if(b){r.name="lishi";r.sex="man";b = false;}else{r.name="李四";r.sex="男";b = true;}r.bo =true ; r.notify();}}}
}
class Output implements Runnable
{Res  r;Output(Res r){this.r=r;}public void run(){while(true){synchronized(r){if(!r.bo)try{r.wait();}catch(Exception e){}System.out.println(r.name+"  "+r.sex);r.bo=false;r.notify();}}}
}
public class StringDemo {public static void main(String[] args) {Res  r = new Res();Input in = new Input(r);Output out = new Output(r);Thread t = new Thread(in );Thread tl = new Thread(out);t.start();tl.start();}
}

输出结果为

李四  男
lishi  man
李四  男
lishi  man
李四  男
lishi  man
李四  男
lishi  man
李四  男
lishi  man
李四  男
lishi  man
李四  男
lishi  man
李四  男
lishi  man
李四  男

注  :  wait  :

notify()

notifyAll()

都使用在同步中,因为要对持有监视器的线程操作,所以要使用在同步中,因为只有 同步才具有锁;

为什么这些操作线程的方法要定义在object 类中呢?

因为这些方法在操作同步线程中,都必须要标识它们所操作线程的锁,只有同一个锁上的被等待线程,可以被同一个锁上的notify唤醒,不可以对不同锁中的线程进行唤醒,也就是说,等待和唤醒必须是同一个锁,而锁可以是任意对象,所以可以被任意对象调用的方法定义在Object类中

优化后的代码

public class TestDemo {public static void main(String[] args) {Resi  r = new Resi();new Thread(new Inputi(r)).start();new  Thread(new  Outputi(r)).start();}
}
class Resi
{String name;String sex; boolean bo =  false;public synchronized void set(String name ,String sex){if(bo)try{this.wait();}catch(Exception e){}this.name = name;this.sex = sex;bo = true ;this.notify();}public synchronized void out(){if(!bo)try{this.wait();}catch(Exception e){}System.out.println(name +"  "+sex);bo = false;this.notify();}
}class Inputi implements Runnable
{Resi  r;Inputi(Resi r){this.r = r;}public void run(){boolean b =true;while(true){if(b){r.set("lishi","man");b = false;}else{r.set("李四","男");b = true;}}}
}class Outputi implements Runnable
{Resi  r;Outputi(Resi r){this.r = r;}public void run(){while(true)r.out();}

生产者与消费者    线程间的通信

public class StringDemo {public static void main(String[] args) {Resourced r = new Resourced();new Thread(new Producerd(r)).start();//1new Thread(new Producerd(r)).start();//2new Thread(new Consumerd(r)).start();//3new Thread(new Consumerd(r)).start();//4}
}
/** 生产一个,消费一个*/
class Resourced
{private String name;private int count  = 1;private boolean flag = false;public synchronized void set(String name){while(flag)try{wait();}catch(Exception e){}this.name = name+"  "+count++;System.out.println(Thread.currentThread().getName()+"生产者,,,," + this.name);flag = true;this.notifyAll();}public void out(){while(!flag)try{wait();}catch(Exception e){}System.out.println(Thread.currentThread().getName()+"消费者    " + this.name);flag = false;this.notifyAll();}}
class Producerd implements Runnable
{private Resourced res ;Producerd(Resourced res){this.res = res;}public void run(){while(true)'7Bres.set("商品");}}
}
class Consumerd implements Runnable
{private Resourced res;Consumerd(Resourced res){this.res = res;}public void run(){while(true){res.out();}}
}

java中的多线程来看一看基础了相关推荐

  1. Java 中的多线程你只要看这一篇就够了

    作者丨纳达丶无忌 https://www.jianshu.com/p/40d4c7aebd66 引 如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多 ...

  2. Java中的多线程你只要看这一篇就够了

    如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现.说这个话其 ...

  3. Java基础——深入理解Java中的多线程(超级详细,值得你看)

    Java中的多线程 进程(process)是程序的一次执行过程,或是正在运行的有一个程序,或是正在运行的一个程序.是一个动态的过程:有它自身的产生.存在和消亡的过程.--生命周期. 线程(thread ...

  4. 草根方式学习java中的多线程

    草根方式学习java中的多线程 下面有具体的代码和截图 源码点这里 多线程即在同一时间,可以做多件事情(说白了,就是齐头并进) 单线程就是按部就班 创建多线程有2种方式,分别是继承线程Thread类, ...

  5. Java中的多线程编程(超详细总结)

    文章目录 Java中的多线程编程(超详细总结) 一.线程与多线程的概念 二.线程与进程之间的关系 三.一个线程的生命周期 四.多线程的目的和意义 五.线程的实现的方式 Java中的多线程编程(超详细总 ...

  6. JAVA中的多线程(一)

    JAVA中的多线程(一) 进程:是一个正在执行中的程序 每一个进程执行都有一个执行的顺序,该顺序是一个执行路径,或者叫控制单元 线程:就是进程中的一个独立的控制单元 线程在控制着进程的执行 一个进程中 ...

  7. Java中控制多线程顺序执行

    Java中控制多线程顺序执行 一.概述 二.普通示例 三.控制示例 3.1.设置线程优先级 3.2.使用线程类的join() 3.2.1.在主线程join() 3.2.2.在子线程join() 3.3 ...

  8. JAVA中的多线程(八):线程的优先级和yield方法

    JAVA中的多线程(八):线程的优先级和yield方法 优先级代表着抢资源的频率 所有线程默认优先级是5 yield()临时释放线程的执行权 1 class Demo implements Runna ...

  9. JAVA中的多线程与运动仿真(1)——用JAVA来放一场烟花

    JAVA中的多线程与运动仿真(1)--用JAVA来放一场烟花 一.实现效果的简单展示: 初步实现的动态效果为在鼠标点击之后,点击之处出现一簇小球,然后向不同方向散开变大. 利用这一效果,再在后续增加颜 ...

最新文章

  1. C#筛法求出范围内的所有质数
  2. 计算机系统结构sw指令集,《深入理解计算机系统》第三章学习笔记
  3. ajax xmlhttp.responsetext,Ajax:xmlhttp.responseText响应显示完整的内部HTML而不是关闭所需文本...
  4. 七十八、SpringBoot监听rabbitmq和创建交换器,队列
  5. 【PAT甲级 十进制转十三进制】1027 Colors in Mars (20 分) Java版 5/5通过
  6. 无废话WPF系列5:控件派生图
  7. 如何变得有价值,需要突破问题,提高解决各种问题的能力?
  8. oracle仲裁机制,仲裁逻辑设计要点
  9. easyUI datagrid 重复发送URL请求
  10. Linux ---yum源详解
  11. 收藏!深度学习必读10篇经典算法论文总结!
  12. python制作一个简易计算器_最简易的python计算器实现源代码
  13. 软件工程导论患者监护系统
  14. 关于数字化营销,这些知识点你一定要知道
  15. 公式计算机实现,数学公式的计算机表达(精选).doc
  16. 第二工业大学计算机应用大专录取分,上海第二工业大学2017年分省分专业录取分数线...
  17. Verilog加法器设计
  18. 解决安装 ISE14.7 Windows10 时出错
  19. 企业——nginx的图片压缩、https模块、重写规则、盗链
  20. Cannot open D:\Anaconda3\Scripts\pip-script.py 解决

热门文章

  1. ThunderNet:国防科大、旷视提出首个在ARM上实时运行的通用目标检测算法
  2. OpenCV手部关键点检测(手势识别)代码示例
  3. js添加关闭功能_微信小程序开发之添加夜间模式功能
  4. 639 页《深度学习:Deep Learning》硬核课程 PPT 下载
  5. 中国科学院计算机网络信息中心怀柔分中心,计算机网络信息中心怀柔分中心(二期)建设项目荣获2018年度“北京市安装工程优质奖”...
  6. 机器学习实战 | 数据探索(变量变换、生成)
  7. 专业工程师看过来~ | RDD、DataFrame和DataSet的细致区别
  8. tensorflow 特征预处理总结
  9. 在GIS中运用坐标系统
  10. 如何显示python的内置模块_python之模块(内置模块)