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内置 ...
随机推荐
- 【selenium】- webdriver常见api
本文由小编根据慕课网视频亲自整理,转载请注明出处和作者. 1.常见API 2.打开网址 3.操作浏览器 quit()没有完全关闭进程,依旧占用资源. 4.输入框操作 5.选择框操作 6.特殊窗口操作 ...
- hdu-6681 Rikka with Cake
题目链接 hdu-6681 Problem Description Rikka's birthday is on June 12th. The story of this problem happen ...
- CF Edu54 E. Vasya and a Tree DFS+树状数组
Vasya and a Tree 题意: 给定一棵树,对树有3e5的操作,每次操作为,把树上某个节点的不超过d的子节点都加上值x; 思路: 多开一个vector记录每个点上的操作.dfs这颗树,同时以 ...
- cogs 2652. 秘术「天文密葬法」(0/1分数规划 长链剖分 二分答案 dp
http://cogs.pro:8080/cogs/problem/problem.php?pid=vSXNiVegV 题意:给个树,第i个点有两个权值ai和bi,现在求一条长度为m的路径,使得Σai ...
- POJ-1213 How Many Tables( 并查集 )
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1213 Problem Description Today is Ignatius' birthday. ...
- bzoj 2001 CITY 城市建设 cdq分治
题目传送门 题解: 对整个修改的区间进行分治.对于当前修改区间来说,我们对整幅图中将要修改的边权都先改成-inf,跑一遍最小生成树,然后对于一条树边并且他的权值不为-inf,那么这条边一定就是树边了. ...
- CF988D Points and Powers of Two 数学结论题 规律 第十题
Points and Powers of Two time limit per test 4 seconds memory limit per test 256 megabytes input sta ...
- Webstorm 的设置
背景色
- 【Offer】[64] 【求1+2+...+n】
题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 求1+2+...+n,要求不能使用乘除法.for. while if else. switch. case等关键字及条件判断语句( A? ...
- PHP如何解决表单重复提交
利用session 表单隐藏域中存放session(表单被请求时生成的标记).采用此方法在接收表单数据后,检查此标志值是否存在,先进行删除,然后处理数据; 若不存在,说明已提交过,忽略本次提交. ...