java多线程学习
在java中要想实现多线程,有两种手段,一种是继续Thread类,另外一种是实现Runable接口。
一、扩展java.lang.Thread类
package com.multithread.learning;
/**
*@functon 多线程学习
*@author 刁兆建
*@time 2016.10.17
*/
class Thread1 extends Thread{
private String name;
public Thread1(String name) {
this.name=name;
}
public void run() {
for (int i = ; i < ; i++) {
System.out.println(name + "运行 : " + i);
try {
sleep((int) Math.random() * );
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
}
public class Main { public static void main(String[] args) {
Thread1 mTh1=new Thread1("A");
Thread1 mTh2=new Thread1("B");
mTh1.start();
mTh2.start(); } }
输出:
A运行 : 0
B运行 : 0
A运行 : 1
A运行 : 2
A运行 : 3
A运行 : 4
B运行 : 1
B运行 : 2
B运行 : 3
B运行 : 4
再运行一下:
A运行 : 0
B运行 : 0
B运行 : 1
B运行 : 2
B运行 : 3
B运行 : 4
A运行 : 1
A运行 : 2
A运行 : 3
A运行 : 4
注意:
但是start方法重复调用的话,会出现java.lang.IllegalThreadStateException异常。
Thread1 mTh1=new Thread1("A");
Thread1 mTh2=mTh1;
mTh1.start();
mTh2.start();
输出:
Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Unknown Source)
at com.multithread.learning.Main.main(Main.java:31)
A运行 : 0
A运行 : 1
A运行 : 2
A运行 : 3
A运行 : 4
二、实现java.lang.Runnable接口
/**
*@functon 多线程学习
*@author 刁兆建
*@time 2016.10.17
*/
package com.multithread.runnable;
class Thread2 implements Runnable{
private String name; public Thread2(String name) {
this.name=name;
} @Override
public void run() {
for (int i = ; i < ; i++) {
System.out.println(name + "运行 : " + i);
try {
Thread.sleep((int) Math.random() * );
} catch (InterruptedException e) {
e.printStackTrace();
}
} } }
public class Main { public static void main(String[] args) {
new Thread(new Thread2("C")).start();
new Thread(new Thread2("D")).start();
} }
输出:
C运行 : 0
D运行 : 0
D运行 : 1
C运行 : 1
D运行 : 2
C运行 : 2
D运行 : 3
C运行 : 3
D运行 : 4
C运行 : 4
三、Thread和Runnable的区别
如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。
package com.multithread.learning;
/**
*@functon 多线程学习,继承Thread,资源不能共享
*@author 刁兆建
*@time 2016.10.17
*/
class Thread1 extends Thread{
private int count=;
private String name;
public Thread1(String name) {
this.name=name;
}
public void run() {
for (int i = ; i < ; i++) {
System.out.println(name + "运行 count= " + count--);
try {
sleep((int) Math.random() * );
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
} public class Main { public static void main(String[] args) {
Thread1 mTh1=new Thread1("A");
Thread1 mTh2=new Thread1("B");
mTh1.start();
mTh2.start(); } }
输出:
B运行 count= 5
A运行 count= 5
B运行 count= 4
B运行 count= 3
B运行 count= 2
B运行 count= 1
A运行 count= 4
A运行 count= 3
A运行 count= 2
A运行 count= 1
从上面可以看出,不同的线程之间count是不同的,这对于卖票系统来说就会有很大的问题,当然,这里可以用同步来作。这里我们用Runnable来做下看看:
/**
*@functon 多线程学习 继承runnable,资源能共享
*@author 刁兆建
*@time 2016.10.17
*/
package com.multithread.runnable;
class Thread2 implements Runnable{
private int count=;
@Override
public void run() {
for (int i = ; i < ; i++) {
System.out.println(Thread.currentThread().getName() + "运行 count= " + count--);
try {
Thread.sleep((int) Math.random() * );
} catch (InterruptedException e) {
e.printStackTrace();
}
} } }
public class Main { public static void main(String[] args) { Thread2 my = new Thread2();
new Thread(my, "C").start();//同一个mt,但是在Thread中就不可以,如果用同一个实例化对象mt,就会出现异常
new Thread(my, "D").start();
new Thread(my, "E").start();
} }
输出:
C运行 count= 15
D运行 count= 14
E运行 count= 13
D运行 count= 12
D运行 count= 10
D运行 count= 9
D运行 count= 8
C运行 count= 11
E运行 count= 12
C运行 count= 7
E运行 count= 6
C运行 count= 5
E运行 count= 4
C运行 count= 3
E运行 count= 2
这里要注意每个线程都是用同一个实例化对象,如果不是同一个,效果就和上面的一样了!
总结:
实现Runnable接口比继承Thread类所具有的优势:
1):适合多个相同的程序代码的线程去处理同一个资源
2):可以避免java中的单继承的限制
3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立
提醒一下:main方法其实也是一个线程。在java中所以的线程都是同时启动的,至于什么时候,哪个先执行,完全看谁先得到CPU的资源。
在java中,每次程序运行至少启动2个线程。一个是main线程,一个是垃圾收集线程。因为每当使用java命令执行一个类的时候,实际上都会启动一个JVM,每一个jVM实习在就是在操作系统中启动了一个进程。
三、常用函数说明
①sleep(long millis): 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)
②join():指等待t线程终止。
/**
*@functon 多线程学习,join
*@author 林炳文
*@time 2015.3.9
*/
package com.multithread.join;
class Thread1 extends Thread{
private String name;
public Thread1(String name) {
super(name);
this.name=name;
}
public void run() {
System.out.println(Thread.currentThread().getName() + " 线程运行开始!");
for (int i = ; i < ; i++) {
System.out.println("子线程"+name + "运行 : " + i);
try {
sleep((int) Math.random() * );
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " 线程运行结束!");
}
} public class Main { public static void main(String[] args) {
System.out.println(Thread.currentThread().getName()+"主线程运行开始!");
Thread1 mTh1=new Thread1("A");
Thread1 mTh2=new Thread1("B");
mTh1.start();
mTh2.start();
System.out.println(Thread.currentThread().getName()+ "主线程运行结束!"); } }
输出结果:
main主线程运行开始!
main主线程运行结束!
B 线程运行开始!
子线程B运行 : 0
A 线程运行开始!
子线程A运行 : 0
子线程B运行 : 1
子线程A运行 : 1
子线程A运行 : 2
子线程A运行 : 3
子线程A运行 : 4
A 线程运行结束!
子线程B运行 : 2
子线程B运行 : 3
子线程B运行 : 4
B 线程运行结束!
发现主线程比子线程早结束
加join
public class Main {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName()+"主线程运行开始!");
Thread1 mTh1=new Thread1("A");
Thread1 mTh2=new Thread1("B");
mTh1.start();
mTh2.start();
try {
mTh1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
mTh2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+ "主线程运行结束!");
}
}
运行结果:
main主线程运行开始!
A 线程运行开始!
子线程A运行 : 0
B 线程运行开始!
子线程B运行 : 0
子线程A运行 : 1
子线程B运行 : 1
子线程A运行 : 2
子线程B运行 : 2
子线程A运行 : 3
子线程B运行 : 3
子线程A运行 : 4
子线程B运行 : 4
A 线程运行结束!
主线程一定会等子线程都结束了才结束
四、线程同步:
synchronized关键字 synchronized关键字可以作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块。如果再细的分类,synchronized可作用于instance变量、object reference(对象引用)、static函数和class literals(类名称字面常量)身上。
1. 把synchronized当作函数修饰符时,示例代码如下:
Public synchronized void methodAAA()
{
//….
}
public void methodAAA()
{
synchronized (this) // (1)
{
//…..
}
}
java多线程学习的更多相关文章
- Java多线程学习笔记
进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间.(只负责空间分配) 线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程. 多线程:一个进程中时可以有多个线 ...
- Java多线程学习(转载)
Java多线程学习(转载) 时间:2015-03-14 13:53:14 阅读:137413 评论:4 收藏:3 [点我收藏+] 转载 :http://blog ...
- java多线程学习笔记——详细
一.线程类 1.新建状态(New):新创建了一个线程对象. 2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...
- 【转】Java多线程学习
来源:http://www.cnblogs.com/samzeng/p/3546084.html Java多线程学习总结--线程概述及创建线程的方式(1) 在Java开发中,多线程是很常用的,用得好的 ...
- JAVA多线程学习笔记(1)
JAVA多线程学习笔记(1) 由于笔者使用markdown格式书写,后续copy到blog可能存在格式不美观的问题,本文的.mk文件已经上传到个人的github,会进行同步更新.github传送门 一 ...
- Java多线程学习(六)Lock锁的使用
系列文章传送门: Java多线程学习(二)synchronized关键字(1) Java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Java多 ...
- Java多线程学习(五)线程间通信知识点补充
系列文章传送门: Java多线程学习(二)synchronized关键字(1) Java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Java多 ...
- Java多线程学习(四)等待/通知(wait/notify)机制
转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79690279 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...
- Java多线程学习(三)volatile关键字
转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79680693 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...
- Java多线程学习(二)synchronized关键字(2)
转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79670775 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...
随机推荐
- java Servlet+mysql 调用带有输入参数和返回值的存储过程(原创)
这个数据访问的功能,我在.NET+Mysql .NET+Sqlserver PHP+Mysql上都实现过,并且都发布在了我博客园里面,因为我觉得这个功能实在是太重要,会让你少写很多SQL语句不说,还 ...
- Windows 安装启动apache时出现错误的解决方法
配置安装Apache主服务发生错误:(OS 5)拒绝访问. : AH00369: Failed to open the Windows service manager, perhaps you fo ...
- Play!中使用HTTP异步编程
本章译者:@Sam Liu (译者未留下自己的主页,请Sam Liu见此文,加入群168013302联系‘大黄蜂@翻译play’) 这一章主要讲解如何运用异步模式实现典型的长连接(long-polli ...
- ASP.NET 多语言的实现(后台消息+前台消息+页面自动绑定)
一 前言 界面支持多种语言,在使用ASP.NET自带的多语言方案时遇到下列问题: 在做管理类的功能时,有添加.修改和查看页面,需要支持多语言的控件基本相同,但要维护多处,产生冗余(ASP.NET有共享 ...
- Vue-router中文教程-Vue-router参考手册.CHM
下载地址http://download.csdn.net/detail/shouce_ren/9689243 百度云下载地址
- Dynatable – 基于 HTML5 & jQuery 的交互表格插件
Dynatable 一款有趣的,语义化,交互式的表格插件,使用 jQuery,HTML5 和 JSON 实现.Dynatable 的目的是提供一种简单的.可扩展的 API,能够轻松的浏览和操作大规模的 ...
- DOM中的事件处理概览与原理的全面剖析
事件是一种异步编程的实现方式,本质上是程序各个组成部分之间的通信,DOM支持大量的事件: 本文通过这几点向大家详细解析事件处理的基本原理:事件类型.事件目标.事件处理程序.事件对象.事件传播 最后再向 ...
- .NET web开发之WebApi初试水
前几天看了.NET的EF(Entity Framework),发现居然有这么先进的东西,只要操作几个类就可以完成数据库的增删查改,而且可以用数据库直接导出类(DB First).也可以用类来生成数据库 ...
- ARCGIS server没有服务、silverlight不能调试、windows server2008安装时跳出“安装程序无法创建新的系统分区也无法定位现有的系统分区”的解决方案
1.某个系统服务没开启 2.默认浏览器设置为IE.(IE内核有时候也不能调试) 3.BIOS里面的SATA设置为开启.
- Python统计学技术环境
http://www.lfd.uci.edu/~gohlke/pythonlibs/#sympy 1.1. Python 1.1.1. NumPy pip install numpy-1.11.0+m ...