java多线程技术核心
1.进程的三大特征:
独立性:拥有自己的独立的地址空间,一个进程不可以直接去访问其他进程的地址空间。
动态性:是一个系统中活动的指令的集合。
并发性:单个进程可以在多个处理器上并发进行,互不影响。
2.并发性和并行性的区别:
并行是同一个时刻,有多条指令在多个处理器上同时的进行;并发是,快速轮换执行,其实上在宏观上,多个进程同时进行。
3.线程的特点:
一个线程必须有属于自己的一个父进程;线程可以有属于自己的堆栈,程序计数器,局部变量;线程可以和其他的线程共享父进程里的全部的资源;线程不知道是否还有其他的线程存在,线程是抢占的方式进行的。
4.多线程编程:
共享资源;创建线程时为其分配资源的代价小;java内置多线程的支持。
5.线程的创建:
方法一:继承thread类创建进程
Public class firstThread extends Thread
{
Private int i;
Public void run(){
Sop(getName());
}
Public static void main(String[] args){
//创建第一个线程
New firstThread().start();
//创建第二个线程
New firstThread().start();
}
}
特点:多个线程无法共享实例变量。
方法二:实现Runnable接口创建线程类
Public class firstThread extends Thread
{
Private int i;
Public void run(){
Sop(Thread.currentThread.getName());
}
Public static void main(String[] args){
//创建第一个线程
firstThread ft = new firstThread();
New Thread(st,”线程1”).start();
}
}
特点:可以共享线程类的实例变量
原因:程序所创建的只是线程的target,多个线程可以共享一个target,所以可以共享一个线程类的实例变量。
6.线程的生命周期:
新建和就绪:
1)New 时便建立了新的线程,处于新建状态,jvm为其分类了内存,初始化了成员变量的值。
2)启动线程用start 方法,不可以直接调用run方法,否则会将run方法当作是一般的方法来对待处理。
运行和阻塞状态,线程死亡。
7.控制线程:join方法,当调用时,线程将会被阻塞,直到调用join方法的线程执行完毕后,才可以,继续往下执行。
8.后台线程:守护线程,精灵线程,如果所有的前台的线程都死亡了,才会自动死亡。
thread对象的setDaemon()方法,去显示地设置。,但是必须在start方法执行之前去设置。
9.线程睡眠:sleep(),在睡眠时间段内,线程不会获得执行的机会,即使没有可以执行的其他的进程,处于sleep的线程也不会去执行。
Thread.sleep(1000);
睡1000ms
10.线程让步:让当前正在执行的线程暂停,但是不会去阻塞线程,只是将它转入到就就绪的状态,让系统的线程调度器进行重新的调度。当某一个方法执行让步后,只有与它优先级相同或者优先级比他的要高的就绪的线程会得到去执行的机会。
11.线程的同步问题:
目录结构:

实例分析:
package TongBu;
public class Account {
//declare the account number
private String accountNo;
public String getAccountNo() {
return accountNo;
}
public void setAccountNo(String accountNo) {
this.accountNo = accountNo;
}
//declare the money
private double balance;
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
//constructor of the accountNo and balance
public Account(String accountNo, double balance) {
super();
this.accountNo = accountNo;
this.balance = balance;
}
//overriding the hashCode method and equals method to make sure it is a same user
public int hashCode(){
return accountNo.hashCode();
}
public boolean equals(Object obj){
if(this==obj){
return true;
}
if(obj!=null&&obj.getClass()==Account.class){
//tranverse the obj to a account target
Account target = (Account)obj;
if(target.getAccountNo()==accountNo){
return true;
}else{
return false;
}
}
return false;
}
}
package TongBu;
public class DrawThread extends Thread{
//user's account id
private Account account;
//the money number of user want to draw
private double drawAmount;
//contructor of DrawThread
public DrawThread(String name,Account account,double drawAmount){
super(name);
this.account=account;
this.drawAmount=drawAmount;
}
//the thread main run function
public void run(){
synchronized(account){
//check the remain money is enough
//if the original money can is sufficient
if(account.getBalance()>=drawAmount){
System.out.println("Draw money successfullly!:"+drawAmount);
//update the remain money
account.setBalance(account.getBalance()-drawAmount);
//output the remain money
System.out.println("Remain money is:"+account.getBalance());
}else{
System.out.println("Draw money failed!");
}
}
}
}
package TongBu;
public class DrawTest {
public static void main(String[] args) {
//instance a account object
Account acct = new Account("10001",10000);
//let two thread to draw money from the same account
new DrawThread("shareing",acct,8000).start();
new DrawThread("mm",acct,8000).start();
}
}
方法一:用synchronized(obj){
}
方法二:同步锁:
Class X{
Priavte final ReentrantLock lock = new ReentrantLock();
Public void m(){
//jiasuo
Lock.lock();
Try{
//////
}
Finally{
//jiesuo
Lock.unlock();
}
}
}
12.线程通信:
1)传统方法:Wait() notify() notifyAll()
2)使用condition控制
package TongXin;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Account {
//define a lock object
private final Lock lock = new ReentrantLock();
//get the condition of object
private final Condition cond = lock.newCondition();
// mark to check there is remain money
private boolean flag=false;
//declare the account id
private String accountNo;
public String getAccountNo() {
return accountNo;
}
public void setAccountNo(String accountNo) {
this.accountNo = accountNo;
}
//declare the money
private double balance;
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
//constructor of the accountNo and balance
public Account(String accountNo, double balance) {
super();
this.accountNo = accountNo;
this.balance = balance;
}
//overriding the hashCode method and equals method to make sure it is a same user
public int hashCode(){
return accountNo.hashCode();
}
public boolean equals(Object obj){
if(this==obj){
return true;
}
if(obj!=null&&obj.getClass()==Account.class){
//tranverse the obj to a account target
Account target = (Account)obj;
if(target.getAccountNo()==accountNo){
return true;
}else{
return false;
}
}
return false;
}
//the mehod to draw money
public void draw(double drawAmount){
lock.lock();
try{
//no body have deposied money into the account
if(!flag){
cond.await();
}else{
//execute the draw money opreration
System.out.println("Draw money:"+drawAmount);
balance-=drawAmount;
System.out.println("Remain money:"+balance);
//set the flag false means money used up
flag=false;
//notify all thread to deposite money
cond.signalAll();
}
}catch(InterruptedException ex){
ex.printStackTrace();
}
finally{
lock.unlock();
}
}
//the mehod to deposit money
public void deposit(double depositAmount){
lock.lock();
try{
//no body have deposied money into the account
if(flag){
cond.await();
}else{
//execute the draw money opreration
System.out.println("Deposit money:"+depositAmount);
}
balance+=depositAmount;
System.out.println("Remain money:"+balance);
//set the flag false means money used up
flag=true;
//notify all thread to deposite money
cond.signalAll();
}catch(InterruptedException ex){
ex.printStackTrace();
}
finally{
lock.unlock();
}
}
}
package TongXin;
public class DepositThread extends Thread{
private Account account;
private double drawAmount;
public DepositThread(String name,Account account,double drawAmount){
super(name);
this.account=account;
this.drawAmount=drawAmount;
}
public void run(){
for(int i=0;i<5;i++){
account.deposit(drawAmount);
}
}
}
package TongXin;
public class DrawThread extends Thread {
private Account account;
private double drawAmount;
public DrawThread(String name,Account account,double drawAmount){
super(name);
this.account=account;
this.drawAmount=drawAmount;
}
public void run(){
for(int i=0;i<5;i++){
account.draw(drawAmount);
}
}
}
package TongXin;
public class TongXinTest {
public static void main(String[] args){
Account acct = new Account("10101",0);
new DrawThread("draw money",acct,800).start();
new DepositThread("deposit money",acct,800).start();
}
}
3)使用阻塞队列进行控制
java多线程技术核心的更多相关文章
- 赶紧收藏!王者级别的Java多线程技术笔记,我java小菜鸡愿奉你为地表最强!
Java多线程技术概述 介绍多线程之前要介绍线程,介绍线程则离不开进程. 首先 , 进程 :是一个正在执行中的程序,每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元: 线程:就 ...
- Java多线程技术学习笔记(二)
目录: 线程间的通信示例 等待唤醒机制 等待唤醒机制的优化 线程间通信经典问题:多生产者多消费者问题 多生产多消费问题的解决 JDK1.5之后的新加锁方式 多生产多消费问题的新解决办法 sleep和w ...
- Java多线程编程核心(1)
Java多线程编程核心(1) 停止线程 本节主要讨论如何更好停止一个线程.停止线程意味着在线程处理完成任务之前放弃当前操作. 1.停不了的线程 可能大多数同学会使用interrupt()来停止线程,但 ...
- Java多线程技术:实现多用户服务端Socket通信
目录 前言回顾 一.多用户服务器 二.使用线程池实现服务端多线程 1.单线程版本 2.多线程版本 三.多用户与服务端通信演示 四.多用户服务器完整代码 最后 前言回顾 在上一篇<Java多线程实 ...
- Java多线程编程核心 - 对象及变量的并发访问
1.什么是“线程安全”与“非线程安全”? “非线程安全”会在多个线程对同一对象总的实例变量进行并发访问时发生,产生的后果是“脏读”,也就是取到的数据其实是被更改过的. “线程安全”是以获得的实例变量的 ...
- (1)Java多线程编程核心——Java多线程技能
1.为什么要使用多线程?多线程的优点? 提高CPU的利用率 2.什么是多线程? 3.Java实现多线程编程的两种方式? a.继承Thread类 public class MyThread01 exte ...
- Java多线程技术学习笔记(一)
目录: 概述 多线程的好处与弊端 JVM中的多线程解析 多线程的创建方式之一:继承Thread类 线程的状态 多线程创建的方式之二:实现Runnable接口 使用方式二创建多线程的好处 多线程示例 线 ...
- java多线程技术之条件变量
上一篇讲述了并发包下的Lock,Lock可以更好的解决线程同步问题,使之更面向对象,并且ReadWriteLock在处理同步时更强大,那么同样,线程间仅仅互斥是不够的,还需要通信,本篇的内容是基于上篇 ...
- (转载) Java多线程技术
多线程编程一直是学员们比较头痛和心虚的地方,因为线程执行顺序的不可预知性和调试时候的困难,让不少人在面对多线程的情况下选择了逃避,采用单线程的方式,其实只要我们对线程有了明确的认识,再加上java内置 ...
随机推荐
- 导航控制器的根控制器 是滚动性&普通的frame区别
当一个控制器有navigationBar&tabBar: 1.当导航控制器根控制器是tableViewController时,tableView 的frame原点是屏幕左上角,当向tableV ...
- HDU5988 - 2016icpc青岛 - G - Coding Contest 费用流(利用对数化乘为加
HDU5988 题意: 有n个区域,每个区域有s个人,b份饭.现在告诉你每个区域间的有向路径,每条路有容量和损坏路径的概率.问如何走可以使得路径不被破坏的概率最小.第一个人走某条道路是百分百不会损坏道 ...
- lightoj 1105 - Fi Binary Number(dp+思维(斐波那契))
题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1105 题解:这题你会巧妙的发现 1-(1),2-(10),3-(100),5- ...
- hdu6376 度度熊剪纸条 思维
度度熊剪纸条 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Subm ...
- CF1009B Minimum Ternary String 思维
Minimum Ternary String time limit per test 1 second memory limit per test 256 megabytes input standa ...
- 微软发布.Net Core 3.0 RC1,最终版本定于9月23日
2019.9.17 微软 宣布推出.NET Core 3.0 Release Candidate 1.就像Preview 9一样,主要专注于为 .NET Core 3.0 发布最终版本 .现在变得非常 ...
- git之rebase、merge和cherry pick的区别(面试常问)
git flow图例镇楼 merge 这个简单,初学者常用.比如主分支是Dev,最新版本是01.然后小明基于此,搞了个feature 分支A,业务:打酱油.然后在上面多次提交,完成功能迭代开发,如A1 ...
- 网关高可用之keepavlived全流程(安装/配置/验证/解析)
1.场景描述 因为要做网关的高可用,用到了keepalived+nginx,来保证nginx的高可用.(微服务时代之网关及注册中心高可用架构设计),如下图: 安装了keepavlived,走了一些弯路 ...
- servlet 的基础学习
Servlet是sun公司提供的一门用于开发动态web资源的技术. Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完 ...
- 三句话告诉你break、return、continue!
break:终止循环执行循环体下面的代码 return:终止循环并且退出循环所在的方法 continue:终止当前循环,进行下一次循环