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)使用阻塞队列进行控制

时间: 2024-10-04 21:26:09

java多线程技术核心的相关文章

Java多线程技术学习笔记(二)

目录: 线程间的通信示例 等待唤醒机制 等待唤醒机制的优化 线程间通信经典问题:多生产者多消费者问题 多生产多消费问题的解决 JDK1.5之后的新加锁方式 多生产多消费问题的新解决办法 sleep和wait的区别 停止线程的方式 守护线程 线程的其他知识点 一.线程间的通信示例 返目录回 多个线程在处理同一资源,任务却不同. 假设有一堆货物,有一辆车把这批货物往仓库里面运,另外一辆车把前一辆车运进仓库的货物往外面运.这里货物就是同一资源,但是两辆车的任务却不同,一个是往里运,一个是往外运. 下面

Java多线程编程核心 - 对象及变量的并发访问

1.什么是“线程安全”与“非线程安全”? “非线程安全”会在多个线程对同一对象总的实例变量进行并发访问时发生,产生的后果是“脏读”,也就是取到的数据其实是被更改过的. “线程安全”是以获得的实例变量的值是经过同步处理的,不会出现脏读的现象. 2.非线程安全例子?怎么解决? 非线程安全 package com.jvm.thread; public class HasSelfPrivateNum { private int num =  0; public void add(String usern

(1)Java多线程编程核心——Java多线程技能

1.为什么要使用多线程?多线程的优点? 提高CPU的利用率 2.什么是多线程? 3.Java实现多线程编程的两种方式? a.继承Thread类 public class MyThread01 extends Thread {     @Override     public void run() {         super.run();         System.out.println("MyThread01");     } public static void main(S

Java多线程技术学习笔记(一)

目录: 概述 多线程的好处与弊端 JVM中的多线程解析 多线程的创建方式之一:继承Thread类 线程的状态 多线程创建的方式之二:实现Runnable接口 使用方式二创建多线程的好处 多线程示例 线程安全问题现象 线程安全问题产生的原因 同步代码块 同步的好处与弊端 同步的前提 同步函数 验证同步函数的锁 单例模式的线程安全问题的解决方案 死锁示例 一.概述 目录 首先得了解进程,打开我们电脑的windows资源管理器,可以直观看到进程的样子: 进程直观上理解就是正在进行的程序.而每个进程包含

java多线程技术之条件变量

上一篇讲述了并发包下的Lock,Lock可以更好的解决线程同步问题,使之更面向对象,并且ReadWriteLock在处理同步时更强大,那么同样,线程间仅仅互斥是不够的,还需要通信,本篇的内容是基于上篇之上,使用Lock如何处理线程通信. 那么引入本篇的主角,Condition,Condition 将 Object 监视器方法(wait.notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set (wait-set)

Java多线程技术

多线程编程一直是学员们比较头痛和心虚的地方,因为线程执行顺序的不可预知性和调试时候的困难,让不少人在面对多线程的情况下选择了逃避,采用单线程的方式,其实只要我们对线程有了明确的认识,再加上java内置的对多线程的天然支持,多线程编程不再是一道难以逾越的鸿沟. 进程.线程.并发执行 首先我们先来认识一下进程.线程.并发执行的概念: 一般来说,当运行一个应用程序的时候,就启动了一个进程,当然有些会启动多个进程.启动进程的时候,操作系统会为进程分配资源,其中最主要的资源是内存空间,因为程序是在内存中运

(转载) Java多线程技术

多线程编程一直是学员们比较头痛和心虚的地方,因为线程执行顺序的不可预知性和调试时候的困难,让不少人在面对多线程的情况下选择了逃避,采用单线程的方式,其实只要我们对线程有了明确的认识,再加上java内置的对多线程的天然支持,多线程编程不再是一道难以逾越的鸿沟. 进程.线程.并发执行 首先我们先来认识一下进程.线程.并发执行的概念: 一般来说,当运行一个应用程序的时候,就启动了一个进程,当然有些会启动多个进程.启动进程的时候,操作系统会为进程分配资源,其中最主要的资源是内存空间,因为程序是在内存中运

java多线程技术之八(锁机制)

Lock是java.util.concurrent.locks包下的接口,Lock 实现提供了比使用synchronized 方法和语句可获得的更广泛的锁定操作,它能以更优雅的方式处理线程同步问题,我们拿Java线程(二)中的一个例子简单的实现一下和sychronized一样的效果,代码如下: 1 public class LockTest { 2 public static void main(String[] args) { 3 final Outputter1 output = new O

java多线程技术: interrupt() 中断线程, 优雅停止线程及原理

MyThread.class package cn.yilong.edcsapiservice.thread; public class MyThread extends Thread { @Override public void run() { System.out.println("开始睡觉"); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out