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内置 ...
随机推荐
- HTML连载34-背景关联和缩写以及插图图片和背景图片的区别
一.背景属性缩写的格式 1.backgound:背景颜色 背景图片 平铺方式 关联方式 定位方式 2.注意点: 这里的所有值都可以省略,但是至少需要一个 3.什么是背景关联方式 默认情况下,背 ...
- POJ2723 Get Luffy Out解题报告tarjan+2-SAT+二分
今天看到讲2-SAT比较好的blog,感觉微微的理解了2-SAT 传送门 参考: https://blog.csdn.net/leolin_/article/details/6680144 题意:你有 ...
- codeforce617E-XOR and Favorite Number莫队+异或前缀和
传送门:http://codeforces.com/contest/617/problem/E 参考:https://blog.csdn.net/keyboarderqq/article/detail ...
- HDU 4607 Park Visit 树的最大直径
题意: 莱克尔和她的朋友到公园玩,公园很大也很漂亮.公园包含n个景点通过n-1条边相连.克莱尔太累了,所以不能去参观所有点景点. 经过深思熟虑,她决定只访问其中的k个景点.她拿出地图发现所有景点的入口 ...
- bzoj2049 Cave 洞穴勘测 lct
这里比上次多了几个操作. 1. make_root(u) 换根节点, 先access(u), 再splay(u),将u移动到splay树的最顶上, 现在这棵splay对于root来说 只有左子树上有东 ...
- codeforces 789 C. Functions again(dp求区间和最大)
题目链接:http://codeforces.com/contest/789/problem/C 题意:就是给出一个公式 然后给出一串数求一个区间使得f(l,r)最大. 这题需要一个小小的处理 可以设 ...
- 在windows上,使用虚拟机安装苹果操作系统
以下是我这两天安装这个苹果操作系统时,所看的文档,集合.已经成功,再次做一个摘录. 分别看了一下几个链接: http://www.bubuko.com/infodetail-2257390.html ...
- Java集合中List、Set以及Map
概述: List , Set, Map都是接口:List , Set继承至Collection接口,Map为独立接口 Set下有HashSet,LinkedHashSet,TreeSet List下有 ...
- CVE-2018-14418 擦出新火花
笔者<Qftm>原文发布:https://xz.aliyun.com/t/6223 0x00 前言 最近,一次授权的渗透测试项目意外的撞出了(CVE-2018-14418)新的火花,在这里 ...
- Java 中创建对象的 5 种方式!
Java中有5种创建对象的方式,下面给出它们的例子还有它们的字节码 Employee类: class Employee implements Cloneable, Serializable { pri ...