• 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.线程的生命周期:

    新建和就绪:

    1New 时便建立了新的线程,处于新建状态,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)使用阻塞队列进行控制

    带着热忱学技术,带着耐心做技术,带着分享去交流,带着微笑探我们的程序人生!
  • 相关阅读:
    测试管理_测试工作量估算
    Mycat原理、应用场景
    linux负载均衡总结性说明(四层负载/七层负载)
    Spring自动装配Bean的五种方式
    计算机组成原理总结
    MyBatis总结
    系统吞吐量(TPS)、用户并发量、性能测试概念和公式
    初探Nginx服务器的整体架构
    mybatis架构理解
    linux环境上运行.net core 初探
  • 原文地址:https://www.cnblogs.com/jiaqingshareing/p/5450430.html
Copyright © 2020-2023  润新知