文档章节

JAVA学习日志(11-1-线程及多线程概述)

Almon
 Almon
发布于 2016/08/12 15:46
字数 1206
阅读 7
收藏 1
点赞 0
评论 0

进程:一个正在执行中的程序,每一个进程执行都有一个执行顺序

            该顺序就是一个执行路径/控制单元

线程:进程中的一个独立控制单元,控制着进程的执行

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

    eg.Java VM启动时会有一个进程java.exe

        该进程中至少有一个线程负责java程序的执行,而且这个线程运行的代码存在于

        main方法中,该线程成为主线程

        扩展:jvm启动不止一个线程,还有负责垃圾回收机制的线程

如何定义一个线程:Java-API-Thread类-继承Thread类

/* 
	1.定义类继承Thread
	2.复写Thread中的run方法
	3.调用线程的start方法:启动线程,调用run方法
    **CPU并不是同时进行线程,而是在不同线程之间切换进行
 */
class Demo extends Thread{
	public void run(){
		System.out.println("Demo_Run");
	}
}
class ThreadDemo{
	public static void main(String[] args){
		Demo d=new Demo();
		d.start();
	}
}

多线程运行即互相抢夺CPU的执行权,即多线程的运行具有随机性

为什么要覆盖run方法?

    Thread用于描述线程,该类就定义了一个功能,用于存储线程要运行的代码,该储存

    功能就是run方法,即run用于储存线程要运行的代码

    覆写run()的目的在于储存自定义代码,让线程运行,

    **start()用于开启线程并执行run(),run()仅调用方法,创建线程,并未运行

线程的运行状态

    1.被创建

    2.运行    start()

    3.冻结:放弃执行资格    sleep(time) wait () notify()

    4.消亡    stop()

    **阻塞状态:等待cpu执行权,具备运行资格

获取线程对象及名称

    static Thread currentThread() 获取当前线程对象

    getName() 获取线程名称

    setName()/构造函数 设置线程名称

class Demo extends Thread{
	Demo(String name){
		super(name);
	}
	public void run(){
		for(int x=0;x<60;x++){
			System.out.println(Thread.currentThread()+this.getName()+"Demo_Run"+x);
		}
	}
}
class ThreadDemo{
	public static void main(String[] args){
		Demo d=new Demo("Mark_II");
		d.start();
		for(int x=0;x<60;x++){
			System.out.println("Demo"+x);
		}
	}
}

练习:卖票窗口

Ver 1.0

/* 
需求:简单的卖票程序
	多个窗口同时卖票
*/
class Ticket extends Thread{
	private static int tick=100; //用static 来共享总票数
	public void run(){
		while(true){
			if(tick>0){
				System.out.println(currentThread().getName()+"__"+"sale:"+tick--);
			}
		}
	}
}
class TicketDemo{
	public static void main(String[] args){
		Ticket t1=new Ticket();
		Ticket t2=new Ticket();
		Ticket t3=new Ticket();
		Ticket t4=new Ticket();
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}

V 2.0 解决共享票数的问题

/* 
需求:简单的卖票程序
	多个窗口同时卖票
*/
class Ticket implements Runnable{//extends Thread{
	private int tick=100;
	public void run(){
		while(true){
			if(tick>0){
				System.out.println(Thread.currentThread().getName()+"__"+ "sale:"+tick--);
			}
		}
	}
}
class TicketDemo{
	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();
	}
}
/* 创建线程的第二种方式:实现Runnable接口
	1.定义类实现Runnable接口
	2.覆盖Runnable接口中的run方法
		-将代码存放在该run方法中
	3.通过Thread类建立线程对象
	4.将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数
		-自定义的run方法所属对象是Runnable接口的子类对象
		 所以要让线程去指定对象的run方法,就必须明确该run方法的所属对象
	5.调用Thread类的start方法开启线程并调用Runnable接口子类的run方法 */

实现方式和继承方式的区别

    实现方式:避免了单继承的局限性,建议使用。

                      线程代码存放在接口子类的run()

    继承方式:线程代码存放在Thread的子类run()中

线程的安全问题

/*
    通过分析,发现打印出0,-1,-2等错票
    多线程的运行出现了安全问题

*/

class Ticket implements Runnable{//extends Thread{
	private int tick=100;
	public void run(){
		while(true){
			if(tick>0){
				try{Thread.sleep(10);}catch(Exception e){}
				System.out.println(Thread.currentThread().getName()+"__"+ "sale:"+tick--);
			}
		}
	}
}
class TicketDemo{
	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();
	}
}

问题的原因:
   当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分
   还没有执行完,另一个线程参与进来执行,导致了共享数据的错误
解决办法:
    对多条操作共享数据的语句,只能让一个线程执行完,其他线程不可以参与执行

    Java对于多线程的安全问题提供了专业的解决方式——同步代码块

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


class Ticket implements Runnable{//extends Thread{
	private int tick=400;
	Object obj=new Object();
	public void run(){
		while(true){
			synchronized(obj){
				if(tick>0){
					try{Thread.sleep(10);}catch(Exception e){}
					System.out.println(Thread.currentThread().getName()+"__"+ "sale:"+tick--);
				}
			}
		}
	}
}

 

© 著作权归作者所有

共有 人打赏支持
Almon
粉丝 2
博文 64
码字总数 44346
作品 0
江北
Java面试需要准备哪些多线程并发的技术要点

一、概念 什么是线程 一个线程要执行任务,必须得有线程 一个进程(程序)的所有任务都在线程中执行的 一个线程执行任务是串行的,也就是说一个线程,同一时间内,只能执行一个任务 多线程原理 同一...

码蚁说架构 ⋅ 05/31 ⋅ 0

Java多线程学习(五)线程间通信知识点补充

系列文章传送门: Java多线程学习(一)Java多线程入门 Java多线程学习(二)synchronized关键字(1) java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Ja...

一只蜗牛呀 ⋅ 04/16 ⋅ 0

Java多线程学习(二)synchronized关键字(2)

系列文章传送门: Java多线程学习(一)Java多线程入门 Java多线程学习(二)synchronized关键字(1) java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Ja...

一只蜗牛呀 ⋅ 04/16 ⋅ 0

Java多线程学习(四)等待/通知(wait/notify)机制

系列文章传送门: Java多线程学习(一)Java多线程入门 Java多线程学习(二)synchronized关键字(1) java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Ja...

一只蜗牛呀 ⋅ 04/16 ⋅ 0

Java程序员面试大纲—错过了金三银四,你还要错过2018吗?

跳槽时时刻刻都在发生,但是我建议大家跳槽之前,先想清楚为什么要跳槽。切不可跟风,看到同事一个个都走了,自己也盲目的开始面试起来(期间也没有准备充分),到底是因为技术原因(影响自己...

java高级架构牛人 ⋅ 04/27 ⋅ 0

Java 多线程编程 — 锁优化2

Java多线程编程-(13)- 关于锁优化的几点建议 一、背景 在《 Java多线程编程-(11)-从volatile和synchronized的底层实现原理看Java虚拟机对锁优化所做的努力》 这一篇文章中,我们大致介绍...

晨猫 ⋅ 04/26 ⋅ 0

百词斩Java程序员面试11个问题,你会几个?2018-04-10

近日,我们在w3cschool app开发者头条上,可以看到百词斩Java程序员面经。 在分享百词斩Java面经前,w3cschool特别给程序员小伙伴们带来一些Java学习干货: 0、学习Java必备的3大神器 如果你...

W3Cschool ⋅ 04/10 ⋅ 0

Java 编程之美:并发编程高级篇之一

本文来自作者 追梦 在 GitChat 上分享 「Java 编程之美:并发编程高级篇之一」 编辑 | 工藤 前言 借用 Java 并发编程实践中的话:编写正确的程序并不容易,而编写正常的并发程序就更难了。 ...

gitchat ⋅ 05/24 ⋅ 0

java面试必备之ThreadLocal

按照传统的经验,如果某个对象是非线程安全的,在多线程环境下对象的访问需要采用synchronized进行同步。但是模板类并未采用线程同步机制,因为线程同步会降低系统的并发性能,此外代码同步解...

编程老司机 ⋅ 05/16 ⋅ 0

Java高级程序员面试大纲——错过了金三,你还要错过银四吗

跳槽时时刻刻都在发生,但是我建议大家跳槽之前,先想清楚为什么要跳槽。切不可跟风,看到同事一个个都走了,自己也盲目的开始面试起来(期间也没有准备充分),到底是因为技术原因(影响自己...

Java高级架构 ⋅ 04/27 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Jenkins实践3 之脚本

#!/bin/sh# export PROJ_PATH=项目路径# export TOMCAT_PATH=tomcat路径killTomcat(){pid=`ps -ef | grep tomcat | grep java|awk '{print $2}'`echo "tom...

晨猫 ⋅ 今天 ⋅ 0

Spring Bean的生命周期

前言 Spring Bean 的生命周期在整个 Spring 中占有很重要的位置,掌握这些可以加深对 Spring 的理解。 首先看下生命周期图: 再谈生命周期之前有一点需要先明确: Spring 只帮我们管理单例模...

素雷 ⋅ 今天 ⋅ 0

zblog2.3版本的asp系统是否可以超越卢松松博客的流量[图]

最近访问zblog官网,发现zlbog-asp2.3版本已经进入测试阶段了,虽然正式版还没有发布,想必也不久了。那么作为aps纵横江湖十多年的今天,blog2.2版本应该已经成熟了,为什么还要发布这个2.3...

原创小博客 ⋅ 今天 ⋅ 0

聊聊spring cloud的HystrixCircuitBreakerConfiguration

序 本文主要研究一下spring cloud的HystrixCircuitBreakerConfiguration HystrixCircuitBreakerConfiguration spring-cloud-netflix-core-2.0.0.RELEASE-sources.jar!/org/springframework/......

go4it ⋅ 今天 ⋅ 0

二分查找

二分查找,也称折半查找、二分搜索,是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于...

人觉非常君 ⋅ 今天 ⋅ 0

VS中使用X64汇编

需要注意的是,在X86项目中,可以使用__asm{}来嵌入汇编代码,但是在X64项目中,再也不能使用__asm{}来编写嵌入式汇编程序了,必须使用专门的.asm汇编文件来编写相应的汇编代码,然后在其它地...

simpower ⋅ 今天 ⋅ 0

ThreadPoolExecutor

ThreadPoolExecutor public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, ......

4rnold ⋅ 昨天 ⋅ 0

Java正无穷大、负无穷大以及NaN

问题来源:用Java代码写了一个计算公式,包含除法和对数和取反,在页面上出现了-infinity,不知道这是什么问题,网上找答案才明白意思是负的无穷大。 思考:为什么会出现这种情况呢?这是哪里...

young_chen ⋅ 昨天 ⋅ 0

前台对中文编码,后台解码

前台:encodeURI(sbzt) 后台:String param = URLDecoder.decode(sbzt,"UTF-8");

west_coast ⋅ 昨天 ⋅ 0

实验楼—MySQL基础课程-挑战3实验报告

按照文档要求创建数据库 sudo sercice mysql startwget http://labfile.oss.aliyuncs.com/courses/9/createdb2.sqlvim /home/shiyanlou/createdb2.sql#查看下数据库代码 代码创建了grade......

zhangjin7 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部