`

黑马程序员_多线程

 
阅读更多

 ------- android培训java培训、期待与您交流! ----------

我们使用计算机时,计算机上有很多的程序在执行,每个程序都被称之为一个进程,但是进程在执行的过程中,往往我们会看到一个程序同时做着多件不同的事情,其实并不是这样子的,这就是利用了多线程,每个事情就是一个线程,程序在执行过程中不断的来回切换正在执行线程,只不过CPU的执行速度太快以至于我们认为程序在同时做着不同的事情。现在我们就来看看如何使用java开发多线程。

java创建多线程有两种方式。

java中提供了一类一接口两种方式创建多线程,类是Thread类,接口是Runnable接口

方式一:通过查找API发现Thread类是一个抽象类,我们要创建抽象类的实例实际上需要的是抽象类的子类对象。

对象的问题解决了以后,我们又该如何启动线程,我们要用多线程做的事情又该怎么写呢?

其实在Thread类中提供了两个方法一个是run()方法,一个是start()方法,根据API中的介绍我们启动线程调用的是start()方法,并且start()方法的底层其实也是调用run()方法。我们需要线程做得事情的代码也是放在了run()方法中。

首先创建Thread类的子类MyThread类

其次重写run()方法

最后在main方法中创建子类对象并开启线程

package cn.itheima01;

public class MyThread extends Thread{
	@Override
	public void run() {
		for(int x = 0; x < 100; x++){
			System.out.println(this.getName()+"--"+x);
		}
	
	}
}

package cn.itheima01;

public class MyThreadDemo {

	public static void main(String[] args) {

		MyThread mt1 = new MyThread();
		MyThread mt2 = new MyThread();
		
		mt1.start();
		mt2.start();
		
	}

}
这样一个简单的多线程的例子就写完了。

方式二:通过接口去实现多线程,java提供了Runnable接口,只需要提供Runnable接口的子类对象同样可以完成上述的操作,下面我们就来看看怎么做的。

package cn.itheima02;

public class MyRunnable implements Runnable{

	@Override
	public void run() {

		for(int x = 0; x < 100; x++){
			System.out.println(Thread.currentThread().getName()+","+x);
		}
		
	}

}

package cn.itheima02;

public class MyThreadDemo {

	public static void main(String[] args) {

		MyRunnable mr1 = new MyRunnable();
		Thread th1 = new Thread(mr1);
		Thread th2 = new Thread(mr1);
		
		th1.start();
		th2.start();
			
	}

}
以上两种方法,就是使用java实现多线程的方法,其实以上两种放发我们发现了还有很大的缺陷,就是数据不能共享。

那么java就提供了一个机制,同步机制。同步进制就是对线程加锁,只有锁对象是同一个时,程序才会往下执行

下面我们来看看java是怎么利用锁机制来同步的。

java提供了关键字synchronized,

需求:卖票,假设现在有100张票,有两个窗口同时进行售票,用程序实现

分析:两个窗口同时进行售票的话,就代表了有两个线程。数据是100

package cn.itheima10;

public class SellTicket implements Runnable {
	private int tickets = 100;
	private Object obj = new Object();

	@Override
	public void run() {

		while (true) {
			synchronized (obj) {
				if (tickets > 0) {
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}

					System.out.println(Thread.currentThread().getName()
							+ "正在出售第" + (tickets--) + "张电影票");
				}
			}
		}

	}
}
上面类中用到了一个sleep()方法,sleep()方法用于让线程休眠,100所指的是100毫秒。
package cn.itheima10;

public class ThreadTicketDemo {

	public static void main(String[] args) {

		SellTicket st = new SellTicket();
		
		Thread t1 = new Thread(st,"售票窗口1");
		Thread t2 = new Thread(st,"售票窗口2");
		Thread t3 = new Thread(st,"售票窗口3");
		
		t1.start();
		t2.start();
		t3.start();
		
	}

}

其实上述方法使用的是同步代码块去实现,我们可以将同步代码块换成同步方法去实现,不过从上面的例子我们发现,用的是Object对象锁,那么同步方法的锁又是什么呢?

SellTicket类中的售票部分改成普通方法和静态

package cn.itheima11;

public class SellTicket implements Runnable {
	private static int tickets = 100;
	private Object obj = new Object();
	private int x = 0;
	@Override
	public void run() {

		while (true) {
			if(x%2==0){
				synchronized (SellTicket.class) {
					if (tickets > 0) {
						try {
							Thread.sleep(100);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}

						System.out.println(Thread.currentThread().getName()
								+ "正在出售第" + (tickets--) + "张电影票");
					}
				}
			}else{
				sell();
			}
			x++;
		}

	}
	private synchronized void sell() {
		
			if (tickets > 0) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}

				System.out.println(Thread.currentThread().getName()
						+ "正在出售第" + (tickets--) + "张电影票");
			}
		
	}
}

package cn.itheima11;

public class SellTicket implements Runnable {
	private static int tickets = 100;
	private Object obj = new Object();
	private int x = 0;
	@Override
	public void run() {

		while (true) {
			if(x%2==0){
				synchronized (SellTicket.class) {
					if (tickets > 0) {
						try {
							Thread.sleep(100);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}

						System.out.println(Thread.currentThread().getName()
								+ "正在出售第" + (tickets--) + "张电影票");
					}
				}
			}else{
				sell();
			}
			x++;
		}

	}
	private static synchronized void sell() {
		
			if (tickets > 0) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}

				System.out.println(Thread.currentThread().getName()
						+ "正在出售第" + (tickets--) + "张电影票");
			}
		
	}
}
改成以上方法实现,效果一样,但是同步方法和静态同步方法的的锁对象是什么呢?

其实同步方法的锁对象是this

而静态同步方法的锁对象是当前类对象的字节码文件







分享到:
评论

相关推荐

    黑马程序员_张孝祥_Java多线程与并发库 视频+代码+资料

    黑马程序员_张孝祥_Java多线程与并发库,视频+代码+资料

    黑马程序员_张孝祥_Java多线程与并发库

    黑马程序员_张孝祥_Java多线程与并发库,老师讲的非常仔细,老师很有耐心.欢迎大家下载学习.

    多线程高新(黑马程序员)

    NULL 博文链接:https://lvwenwen.iteye.com/blog/1470696

    黑马程序员-java多线程技术01

    NULL 博文链接:https://huangminwen.iteye.com/blog/1157983

    java并发库高级应用源码--张孝祥

    java并发库thread使用,传统线程技术、定时器技术、线程互斥技术,同步通讯技术、多线程共享数据、并发库应用,线程锁技术,阻塞锁、阻塞队列,线程池等应用

    黑马程序员–Java多线程讲解笔记

    当一个进程中线程有多个时,是多线程。  为什么要用多线程  1,让计算机"同时"做多件事情,节约时间。  2,后台运行程序,提高程序的运行效率.。  3,多线程可以让程序"同时"处理多个事情。  4,...

    传智播客.黑马程序员《Java 基础入门》课后习题答案

    1、 面向对象、跨平台性、健壮性、安全性、可移植性、多线程性、动态性等。 2、 JRE(Java Runtime Environment,Java 运行时环境),它相当于操作系统部分,提供了 Java 程序运 行时所需要的基本条件和许多 Java ...

    传智播客_Java培训_毕向东_Java基础[05-多线程]

    传智播客_Java培训_毕向东_Java基础[05-多线程]系黑马程序员_毕向东_Java基础视频教程

    黑马程序员 安卓学院 万元哥项目经理 分享220个代码实例

    |--利用FinalHttp实现多线程断点续传 |--加密之MD5 |--动画Animation详解 |--动画之view左右抖动 |--动画之移动动画 |--动画之组合动画 |--动画之缩放动画ScaleAnimation |--反序列化对象 |--发送短信 读天气 调音量...

    java拼图游戏源码.zip

    这是一个java写的拼图游戏,用了swing、多线程等知识,可以设置行数列、列数、还有使用多线程写的游戏动画,拼图的图块具有磁贴设计,代码封装性较强,容易移植,纯原创。

    图解java多线程设计模式

    日本资-深技术作家、《程序员的数学》作者结城浩执笔,264张图表(UML类图、时序图、Timethreads图等)穿插文中,通过类比手法和浅显的语言,逐一讲解与多线程和并发处理相关的12种设计模式。每章附带练习题和答案,...

    图解java多线程设计模式2017年8月最新版

    精选12种与多线程和并发处理相关的设计模式 264张图表 + 300段Java示例程序 = 轻松学习多线程编程 日本经典多线程入门书,原版长销11年! 本书适合以下读者阅读 a.对多线程感兴趣的人 b.对Java编程感兴趣的人 c.对...

    8天快速掌握Android系列视频之04_开发与 运行(卸载)第一个ANDROID应用

    黑马程序员_8天快速掌握Android视频 总共67个视频教程,包括:02_搭建Android开发环境,03_创建与启动手机模拟器和学习使用ANDROID操作系统,04_开发与 运行(卸载)第一个ANDROID应用,05_项目的目录结构与安装及...

    8天快速掌握Android系列视频之07_查看应用输出的错误信息 与如何部署应用到真实手机

    黑马程序员_8天快速掌握Android视频 总共67个视频教程,包括:02_搭建Android开发环境,03_创建与启动手机模拟器和学习使用ANDROID操作系统,04_开发与 运行(卸载)第一个ANDROID应用,05_项目的目录结构与安装及...

    拼图游戏 (源码+所有文件)

    萌新做的一个简单的Java拼图游戏 启动类:pers.sept.jigsaw1.swing下的...多线程。 下拉列表选择数字可以切换关卡图片,最后的“+”,可以添自己的图片到关卡中。 设有背景音乐 有一键通过按钮 等等,块下载去看看吧。

    图解java多线程设计模式 2017年8月最新版

    这本书的pdf文件有162M,是最新版高清的pdf,网上原书售价60多元,这里提供的附件是百度云的链接地址。

    《Java基础案例教程(第2版)》课后习题答案1

    第1章 Java开发入门一.填空题1. 面向对象,SUN 2. JavaSE,JavaEE,JavaME3.面向对象、跨平台性、支持多线程4. JDK5.bin

    JAVA核心知识点整理.pdf

    给大家分享一篇我在学习java过程中...包含常见的面试题:JVM、Java集合、多线程并发、java基础、SSM框架原理、微服务、Netty和RPC、网络、日志、算法、数据结构、加密、分布式算法、机器学习、大数据等知识点,都是干货

    mfc教程(word版)

    4.4.3.2 命令消息的派发和消息的多次处理 67 4.4.3.3 一些消息处理类的OnCmdMsg的实现 69 4.4.3.4 一些消息处理类的OnCommand的实现 71 4.4.4 对控制通知消息的接收和处理 72 4.4.4.1 WM_COMMAND控制通知消息的处理 ...

    黑马JVM学习笔记二

    title: 黑马JVM学习笔记二 date: 2020-01-13 1:00:00 ...线程是私有的,多线程之间分别有各自的程序计数器记录对应线程的执行位置 程序计数器是Java虚拟机规范中唯一一个不会存在内存溢出的区(堆和栈等会出现内存溢

Global site tag (gtag.js) - Google Analytics