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内置 ...
随机推荐
- The Best Path(HDU5883)[欧拉路]2016青岛online
题库链接:http://acm.hdu.edu.cn/showproblem.php?pid=5883 欧拉回路裸题,第一次接触欧拉路的我是真的长见识了^-^ 懂了欧拉路这道题就是没什么问题了,欧拉路 ...
- sql建表经验总结——主要是建表现象
在建表方面你都有哪些感悟? 见过的建表的一些现象: 1,一对多业务,有时候在主表见一个字段xxIds,然后存多表的id,多个英文逗号隔开,不知道这样好不好? 2,大部分字段建成varchar(50), ...
- Oracle - Sequences
创建计数器 --最小值1,最大值999999999999999999999999999,从1开始,每次自增1,缓存20 --SQL语句: -- Create sequence create seque ...
- 持续集成高级篇之Jenkins资源调度
系列目录 之前的示例我们主要关注点在于功能的实现,都是在一个节点的完成了.有了多个节点后,必须涉及到资源的调度问题.本节我们讲解在创建任务时与资源调度的有关选项以及一些平时没有注意到的但在生产环境需要 ...
- hdu 3709 Balanced Number(数位dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3709 题意:给定区间[a,b],求区间内平衡数的个数.所谓平衡数即有一位做平衡点,左右两边数字的力矩相 ...
- bzoj5072 小A的树 题解
题意 给出一棵 n 个点的树,每个点有黑白两种颜色.q 次询问,每次 询问给出 x 和 y,问能否选出一个 x 个点的联通子图,使得其中 黑点数目为 y. 范围 n ≤ 5000,q ≤ 10^5 其 ...
- HTML图片死活不显示
图片不显示: 1.路径 2.名称 3.少写了" ... " 正确的例子:“../images/dd.png” 4.多写了一个“/” ,或者少写了一个“ . ” ,没错.不是三个点, ...
- GraphQL Java-入门指南
GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时. GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任 ...
- 【Offer】[15] 【二进制中1的个数】
题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 思路分析 让整数和1相与,可以判断整数二进制表示中最右边一位是否为1, ...
- 深入理解 ThreadLocal
前言 上篇文章 深入理解 Handler 消息机制 中提到了获取线程的 Looper 是通过 ThreadLocal 来实现的: public static @Nullable Looper myLo ...