对于多线程并发的思考:第一版

        进程与多线程的概念,在如今高并发的数据操作环境中已经深入人心。那进程的概念与多线程的概念很多计算机的学习者却知之甚少,那就先让我们来了解以下进程与多线程的概念吧。

        什么是进程,举个例子,就是运行在计算机上的一段程序,是系统进行资源分配和调度的一个基本单位。当你打开windows系统中的任务管理器,查看当前运行进程时,那些正在你电脑上使用资源,占用内存,使用CPU的程序就是一个个进程。

        什么时线程呢?线程时进程内部的子单位,一个进程中会有一个到多个线程去执行自己的任务,这些线程进行并发操作,恪尽职守,共同完成进程所正在执行的任务。举个例子,如果你打开QQ这个应用程序,这就是一个进程,而随之需要的聊天功能,传输数据功能,加载图片功能,听歌看视频等功能,就是一个个线程正在操作和执行的。线程之间执行并发操作,其实是微观串行,宏观并行,因为每一个线程需要使用CPU时,总是只有一个线程在占用CPU,其他线程在后面等待,由于一些内部处理的机制和切换时间短,人根本察觉不到这样的切换状态,所以会感觉线程之间都是并行操作,其实是串行操作。

       那系统为什么要进行多线程并发,而不是单线程操作呢?比方说,任务1和任务2完全独立,互不相关,任务1是在等待y

远程服务器返回数据,以便进行后期的处理,这时CPU一直处于等待状态,一直在空运行。如果任务2是在10秒之后被运行,虽然执行任务2的时间非常短,仅仅是1秒,但也必须在任务1运行结束后才可以运行任务2,这样做,CPU的利用率会非常低。而如果是多线程并发,CPU完全可以在任务1和任务2之间来回切换,使任务2不必等到10秒再运行。这样系统的运行效率大大得到提升。

       使用多线程,就必须掌握多线程的代码操作:

       一:继承Thread类  

package com.mythread.www;

public class MyThread extends Thread{
   public void run() {
       try {
           for(int i=0;i<10;i++) {
               int time = (int)(Math.random()*1000);
               Thread.sleep(time);
               System.out.println("run="+Thread.currentThread().getName());
           }
       }catch(InterruptedException e) {
           e.printStackTrace();
       }
   }
}

package test;

import com.mythread.www.MyThread;

public class Run {
   public static void main(String[]args) {
      try {
          MyThread thread = new MyThread();
          thread.setName("myThread");
          thread.start();
          for(int i=0;i<10;i++) {
              int time = (int)(Math.random()*1000);
              Thread.sleep(time);
              System.out.println("main="+Thread.currentThread().getName());
          }
      }catch(InterruptedException e) {
          e.printStackTrace();
      }
   }
}

由于线程执行的随机性,主线程和MyThread线程的打印顺序很随机。

       二:实现Runnable接口

       

package myrunnable;

public class MyRunnable implements Runnable{

    @Override
    public void run() {
        // TODO Auto-generated method stub
        System.out.println("运行中!");
    }
 
}

package test;

import com.mythread.www.MyThread;

import myrunnable.MyRunnable;

public class Run {
   public static void main(String[]args) {
   Runnable runnable = new MyRunnable();
   Thread thread = new Thread(runnable);
   thread.start();
   System.out.println("运行结束!");
   }
}

介绍完以上多线程实例运行的代码操作,现在让我们来学习一下线程之间的共享数据和不共享数据,以及所造成的非线程安全问题。

首先来说一下数据不共享的情况:

一个线程类中的内部属性,由这个线程类新创建出来的线程,不共享这个内部属性数据。

package com.mythread.www;

public class MyThread extends Thread{
  private int count=5;
  public MyThread(String name) {
      super();
      this.setName(name);
  }
  public void run() {
      super.run();
      while(count>0) {
          count--;
          System.out.println("由 "+this.currentThread().getName()+" 计算,count="+count);
      }
  }
}

package test;

import com.mythread.www.MyThread;

import myrunnable.MyRunnable;

public class Run {
   public static void main(String[]args) {
    MyThread a = new MyThread("A");
    MyThread b = new MyThread("B");
    MyThread c = new MyThread("C");
    a.start();
    b.start();
    c.start();
  }
}

再来说一下数据共享的情况:

package com.mythread.www;

public class MyThread extends Thread{
  private int count=5;
 
  public void run() {
      super.run();
          count--;
          System.out.println("由 "+this.currentThread().getName()+" 计算,count="+count);
      
  }
}

package test;

import com.mythread.www.MyThread;

import myrunnable.MyRunnable;

public class Run {
   public static void main(String[]args) {
    MyThread mythread = new MyThread();
    Thread a = new Thread(mythread,"A");
    Thread b = new Thread(mythread,"B");
    Thread c = new Thread(mythread,"C");
    Thread d = new Thread(mythread,"D");
    Thread e = new Thread(mythread,"E");
    a.start();
    b.start();
    c.start();
    d.start();
    e.start();
  }
}
可是在这段代码中产生了 (由A计算,count=3) (由B计算,count=3)的异常状态,这就叫做非线程安全状态。需要在线程类中的run方法前面加一个synchronized同步锁。这样就是一个临界区,每次只有一个线程可以在临界区中运行,运行完毕后其他线程才能进去。所以很好的解决的非线程安全的问题。

 

 

 

 

 

 

 

 

 

 

 

       

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luolvzhou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值