java学习笔记之初识多线程

初识多线程

一.进程的认识:

  1.进程的理解:

  进程可以理解成正在执行的任务,就是正在运行的程序,进程又分为两种,一种是前台进程,就是我们很直观看见的,另一种是后台进程,就是操作系统启动就有的(系统级的进程),每个进程运行之后都会占用一定的cpu和内存资源;

  比如说:我们打开window任务管理器就可以看到有很多的进程,里面有用户开启的,也有操作系统启动的进程

  2.进程的调度:

  也就是那么多的进程,cpu是怎样运行的呢?

  采用时间片轮转法

二.线程认识

  1.线程的理解

    线程是在进程的内部运行的执行体

    (1).一个进程可以创建多个线程

    (2).进程和线程共同来争夺cpu,而且概率是均等的

    (3).线程依赖进程,不能独立存在

    (4).在java中,一个进程至少有一个线程,main方法被称为主线程;

      我们可以在java的main方法中输出一个1/0;

    (5).进程或者线程都有优先级,优先级高的可以得到更多的时间片和cpu的执行权

    (6).抢占式调度:优先级高的进程可以抢占优先级低的cpu执行权

  2.为什么要搞多线程?

   原因:

    (1).让多个程序同时执行

    (2).提高程序的执行效率

三.线程的创建

  1.方式一:继承Thread类

    小demo:

1 //定义一个类,继承Thread类
2 public  class  MyThread  extends  Thread {
3
4     //重写Thread类的run方法
5     public void run(){
6         System.out.print("我是一个子线程");
7     }
8 }

  

1 public class Demo {
2     public static void main(String[] args) {
3         //创建子类对象,然后调用start();方法
4         MyThread mt=new MyThread();
5         mt.start();
6     }
7 }

  2.方式二:实现Runnable接口

    小demo:

//实现类的定义
public class MyRunnableImpl  implements Runnable {
    //定义一个Runnable实现类,然后重写run方法
    @Override
    public void run() {
        //这里写功能代码
    }
}
 1 public class Demo {
 2     //使用代码
 3     public static void main(String[] args) {
 4         //new 一个Runnable实现类对象
 5         MyRunnableImpl my=new MyRunnableImpl();
 6         //然后将该实现类对象,传入Thread类的构造方法中,并创建Thread类对象
 7         //调用Thread对象start()方法开启线程
 8         new Thread(my).start();
 9     }
10 }

四.线程的安全

  1.线程安全问题产生的原因:

      当多个线程去访问共享资源时候,就会发生线程安全问题

    先看一个案例:多窗口卖电影票的案例

 1 class  Ticket implements Runnable {
 2     //电影票的数量
 3     private static  int ticket=100;
 4     @Override
 5     public void run() {
 6         while(true){
 7             if(ticket>0){
 8                 //模拟网络延时的场景
 9                 try {
10                     Thread.sleep(50);
11                 } catch (InterruptedException e) {
12                     // TODO Auto-generated catch block
13                     e.printStackTrace();
14                 }
15                 //对票数进行出售(减减操作)
16                 System.out.println("正在售出第"+ticket--+"张票");
17             }
18         }
19     }
20 }
21 public class Demo {
22     public static void main(String[] args) {
23         //new 一个实现类对象
24         Ticket  t=new Ticket();
25         //创建3个线程对电影票进行售卖
26         new Thread(t).start();
27         new Thread(t).start();
28         new Thread(t).start();
29
30     }
31 }

  这时候就出现了问题:

    

    出现这个问题的解释:

      当拥还剩一张电影票的时候,拥有cpu执行权的线程运行到while(true)的时候,顺利通过,然后在运行sleep();这时候这个线程进入堵塞状态,电影票还是1,cpu的执行权被另一个线程拿到,也正好运行到while(true),顺利通过,然后在运行sleep();cpu执行权被第三个线程抢去,同样的运行,到最后醒过来的线程会继续执行下面的代码。就产生了负数票的现象

   2.线程安全问题的解决方案:

     (1).同步代码块

    

 1
 2      //定义一个对象,当做锁对象
 3      static Object obj = new Object();
 4      /*
 5         同步代码块:
 6         参数:锁对象
 7         1:java任何对象都可以作为锁对象
 8         2:所有的线程都必须共享这个锁对象(该对象只有一份)
 9         synchronized(mutex){
10             //存放需要加锁的代码
11         }
12       */
13
14     //实现卖票的代码
15     @Override
16     public void run() {
17
18         while(true){
19             synchronized (obj) {//加锁
20                 if(tickets > 0 ){
21                     //模拟一个网络的延时
22                     try{Thread.sleep(50);}catch(Exception e){}
23                     System.out.println("正在出售第"+ tickets-- + "张票");
24                 }
25             }//解锁
26         }
27     }

    (2).同步方法

 1     /*
 2      * 同步方法:对整个方法加锁
 3      *
 4      * 1:同步方法的锁对象是this,  这里的this必须是同一个
 5      * 2:静态方法的锁对象是:类名.class
 6      */
 7     /*
 8      * 同步代码块和同步方法的区别:
 9      *     1:同步代码块可以对任何一段代码进行加锁
10      *  2:同步方法是对整个方法都进行加锁
11      *
12      *
13      *  3:同步代码块的对象可以自己指定
14      *  4:同步方法的锁对象必须是this
15      */
16     public synchronized void method(){
17         if (tickets > 0) {
18             // 模拟一个网络的延时
19             try {
20                 Thread.sleep(50);
21             } catch (Exception e) {
22             }
23             System.out.println("正在出售第" + tickets-- + "张票");
24         }
25     }
26
27     // 实现卖票的代码
28     @Override
29     public void run() {
30
31         while (true) {
32             method();
33         }
34     }

    (3).同步锁

 1 /*
 2      * 同步锁:
 3      *  Lock接口:
 4      *      ReentrantLock实现类:
 5      *         lock();    加锁
 6      *         unlock();解锁
 7      */
 8
 9     //1:创建锁对象
10     ReentrantLock rt = new ReentrantLock();
11
12
13     // 实现卖票的代码
14     @Override
15     public void run() {
16
17         while (true) {
18             //2:在适当的地方加锁
19             rt.lock();
20
21             if (tickets > 0) {
22                 // 模拟一个网络的延时
23                 try {
24                     Thread.sleep(50);
25                 } catch (Exception e) {
26                 }
27                 System.out.println("正在出售第" + tickets-- + "张票");
28             }
29             //3:在适当的地方解锁
30             rt.unlock();
31         }
32     }

五.线程的状态

  

时间: 2024-08-24 08:20:14

java学习笔记之初识多线程的相关文章

Java学习笔记心得——初识Java

初识Java 拿到这本厚厚的<Java学习笔记>,翻开目录:Java平台概论.从JDK到TDE.认识对象.封装.继承与多态...看着这些似懂非懂的术语名词,心里怀着些好奇与担忧,就这样我开始走进Java的世界.  Java产生的历史 Java来自于Sun公司的一个叫Green Project中撰写的程序语言,全球信息网(World Wide Web)兴起,Java Applet成为网页互动技术的代表,特别适合于Internet应用程序开发. Java语言的特点 1.面向对象 这是Java最重要

Java学习笔记五(多线程)

1.介绍 线程能够使程序具有两条和两条以上的可执行的路径,尤其对多核CPU特别的重要. 2.创建线程 1.继承Thread类 一个类直接的继承Thread类的话,此类就具有了线程的能力,接下来只需要重写继承的run()即可. <span style="font-size:18px;">package com.Thread; //定义实现Runnable接口的类 class MyThread11 extends Thread { //实现run方法,指定线程执行的任务 pub

Java学习笔记_网络+多线程

支持同时收发的客户端和服务器端 客户端 1 import javax.swing.*; 2 import java.awt.*; 3 import java.io.*; 4 import java.net.*; 5 import java.awt.event.*; 6 7 public class ChatClient { 8 private JTextArea incoming; 9 private JTextField outgoing; 10 private PrintWriter wri

JAVA学习笔记(四十一)-多线程与线程组

线程组ThreadGroup /* * 线程组ThreadGroup * * 结论: * 如果在设置线程组优先级之前设置线程优先级,则线程优先级不受线程组优先级限制 * 如果在设置线程组优先级之后设置线程优先级,则线程优先级不能超过线程组优先级 * * 线程的优先级,默认与启动它的父线程相同,但受到所有线程组的限制 */ public class Test02 { public static void main(String[] args) { System.out.println(Thread

Java学习笔记45(多线程二:安全问题以及解决原理)

线程安全问题以及解决原理: 多个线程用一个共享数据时候出现安全问题 一个经典案例: 电影院卖票,共有100座位,最多卖100张票,买票方式有多种,网上购买.自主售票机.排队购买 三种方式操作同一个共享数据,这时候会出现安全问题: 示例: package demo1; public class Tickets implements Runnable { private int ticket = 100; public void run(){ while(true){ if (ticket>0) {

Java学习笔记46(多线程三:线程之间的通信)

多个线程在处理同一个资源,但是线程的任务却不相同,通过一定的手段使各个线程能有效地利用资源, 这种手段即:等待唤醒机制,又称作线程之间的通信 涉及到的方法:wait(),notify() 示例: 两个线程一个输入,一个输出 package demo; public class Resource { public String name; public String sex; } 输入线程: package demo; public class Input implements Runnable

JAVA学习笔记 -- 多线程之共享资源

在多线程程序运行过程中,可能会涉及到两个或者多个线程试图同时访问同一个资源.为了防止这种情况的发生,必须在线程使用共享资源时给资源"上锁",以阻挡其它线程的访问.而这种机制也常常被称为互斥量,本文主要介绍它的两种方式synchronized和Lock . 1.synchronized 当任务要执行被synchronized关键字保护的代码片段的时候,它会检查锁是否可用,然后获取锁,执行代码,释放锁.synchronized也有两种用法: A.synchronized方法 import

java学习笔记14--多线程编程基础1

本文地址:http://www.cnblogs.com/archimedes/p/java-study-note14.html,转载请注明源地址. 多线程编程基础 多进程 一个独立程序的每一次运行称为一个进程,例如:用字处理软件编辑文稿时,同时打开mp3播放程序听音乐,这两个独立的程序在同时运行,称为两个进程 进程要占用相当一部分处理器时间和内存资源 进程具有独立的内存空间 通信很不方便,编程模型比较复杂 多线程 一个程序中多段代码同时并发执行,称为多线程,线程比进程开销小,协作和数据交换容易

java学习笔记9--内部类总结

java学习笔记系列: java学习笔记8--接口总结 java学习笔记7--抽象类与抽象方法 java学习笔记6--类的继承.Object类 java学习笔记5--类的方法 java学习笔记4--对象的初始化与回收 java学习笔记3--类与对象的基础 java学习笔记2--数据类型.数组 java学习笔记1--开发环境平台总结 本文地址:http://www.cnblogs.com/archimedes/p/java-study-note9.html,转载请注明源地址. java内部类分为: