(个人笔记)线程

线程--什么是进程

进程--概念

什么是进程呢?

    进程是指运行中的应用程序,每个进程都有自己独立的地址空间(内存空间),比如用户点击桌面的IE浏览器,就启动了一个进程,操作系统就会为该进程分配独立的地址空间。当用户再次点击左面的IE浏览器,又启动了一个进程,操作系统将为新的进程分配新的独立的地址空间。目前操作系统都支持多进程。

要点:用户每启动一个进程,操作系统就会为该进程分配一个独立的内存空间。

 

线程--概念

什么是线程呢?

    是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。线程有就绪、阻塞和运行三种基本状态。

线程

1、线程是轻量级的进程

2、线程没有独立的地址空间(内存空间)

3、线程是由进程创建的(寄生在进程)

4、一个进程可以拥有多个线程-->这就是我们常说的多线程编程

5、线程有几种状态:

  a、新建状态(new)

  b、就绪状态(Runnable)

  c、运行状态(Running)

  d、阻塞状态(Blocked)

  e、死亡状态(Dead)

 

线程有什么用处

java程序中流传一句话,不会使用线程就别跟别人说自己学过java。目前绝大部分应用程序都会涉及到多并发的问题。只要应用程序涉及到并发,就离不开多线程编程。

 

线程--如何使用

在java中一个类要当作线程来使用有两种方法

1、继承Thread类,并重写run函数

2、实现Runnable接口,并重写run函数

因为java是单继承的,在某些情况下一个类可能已经继承了某个父类,这时在用继承Thread类方法来创建线程显然不可能java设计者们提供了另外一个方式创建线程,就是通过实现Runnable接口来创建线程。

通过继承Thread类来实现建立线程实例[Thread01.java]

/**

 * 演示如何通过继承Thread来开发线程

 */

public class Thread01 {

       public static void main(String[] args) {

              //创建一个 Cat对象

              Cat cat=new Cat();

              //启动线程

              cat.start();//.start()会导致run函数运行

       }

}

 

class Cat extends Thread{

       int times=0;

       //重写run函数

       public void run(){

              while(true){

                     //休眠一秒

                     //1000表示1000毫秒

                     try {

                            Thread.sleep(1000);//sleep就会让该线程进入到Blocked阻塞状态,并释放资源。

                     } catch (Exception e) {

                            e.printStackTrace();

                     }

                     times++;

                     System.out.println("hello,world!"+times);

                     if(times==10){

                            //退出线程

                            break;

                     }

              }

       }

}

-------------------------------------------------------------------------------

通过Runnable接口来实现建立线程实例[Thread02.java]

/**

 * 演示如何通过Runnable接口来开发线程

 */

public class Thread02{

       public static void main(String []args){

              Dog dog=new Dog();

              //创建线程

              Thread t=new Thread(dog);

              //启动线程

              t.start();

       }

}

class Dog implements Runnable{//创建Runnable接口

       public void run(){//重写run函数

              int times=0;

              while(true){

                     try{

                            Thread.sleep(1000);

                     }catch (Exception e) {

                            e.printStackTrace();

                     }

                     times++;

                     System.out.println("hello,wrold!"+times);

                     if(times==10){

                            break;

                     }

              }

       }

}

-------------------------------------------------------------------------------

线程--区别

线程--继承Thread VS 实现Runnable的区别

    从java的设计来看,通过继承Thread或者实现Runnable接口来创建线程本质上没有区别,从jdk帮助文档我们可以看到Thread类本身就实现了Runnable接口,如果一定要说它们有什么区别,总结几点

1、尽可能使用实现Runnable接口的方式来创建线程

2、在使用Thread的时候只需要new一个实例出来,调用start()方法即可以启动一个线程,如: Thread test=new Thread();

              test.start();

3、在使用Runnable的时候需要先new一个实现Runnable的实例,之后用Thread调用,如:

       Test implements Runnable

       Test t=new Test();

       Thread test=new Thread(t);

       tset.start();

-------------------------------------------------------------------------------

线程--深入理解

线程对象只能启动一个线程: 不论继承Thread或实现Rnunable接口都不能使用start启同一个线程2次

结论:不管是通过继承Thread,还是通过实现Runnable接口创建线程,它们的一个对象只能启动(即:start())一次。否则就会有异常抛出。

 

两种创建线程的方法的区别

创建线程有两种方法:1、继承Thread;2、实现Runnable接口;这两种方法有什么区别?

用实现Runnable接口的特点

1、用实现Runnable接口的方法创建对象可以避免java单继承机制带来的局限;

2、用实现Runnable接口的方法,可以实现多个线程共享同一段代码(数据);

因此建议大家如果你的程序有同步逻辑需求,则使用Runnable的方法来创建线程。

java线程的同步--提出问题

多线程的并发,给我们编程带来很多好处,完成更多更有效率的程序。但是也给我们带来线程安全问题。

 

java线程的同步--解决问题

解决问题的关键就是要保证容易出问题的代码的原子性所谓原子性就是指:当a线程在执行某段代码的时候,别的线程必须等到a线程执行完后,它才能执行这段代码。也就是排队一个一个解决。

java处理线程两步的方法非常简单,只需要在需要同步的代码段,用:

       synchronized(Object){你要同步的代码}

即可。

售票案例演示

/**

 * 功能:使用线程的注意事项

 * 线程并发同步锁synchronized(Object){}的使用

 */

public class Thread05 {

       public static void main(String[] args) {

              //定义一个售票窗口

              TicketWindow tw1=new TicketWindow();

             

              //使用三个线程同时启动

              Thread t1=new Thread(tw1);

              Thread t2=new Thread(tw1);

              Thread t3=new Thread(tw1);

             

              t1.start();

              t2.start();

              t3.start();

       }

}

 

//售票窗口类

class TicketWindow implements Runnable {

       //共有2000张票

       private int nums=2000;

       private Dog myDog=new Dog();

 

       public void run() {

              while(true){

                     //出票速度是1秒出一张

                     try {

                            Thread.sleep(1000);

                     } catch (Exception e) {

                            e.printStackTrace();

                     }

 

                     //认为if else要保证其原子性

                     //先判断是否还有票

                     synchronized(myDog){//synchronized(this){}为同步代码块

                            if(nums>0){

                                   //显示售票信息

                                   //Thread.currentThread().getName()得到当前线程的名字

                                   System.out.println(Thread.currentThread().getName()+"正在售出第"+nums+"张票");

                                   nums--;

                            }else{

                                   //售票结束

                                   break;

                            }

                     }

              }

       }

}

 

class Dog{

}

-------------------------------------------------------------------------------

java线程的同步--解决问题

对同步机制的解释:

    java任意类型的对象都有一个标志位,该标志位具有0、1两种状态,其开始状态为1,当某个线程执行了synchronized(Object)语句后,object对象的标志位变为0的状态,直到执行完整个synchronized语句中的代码块后,该对象的标志位又回到1状态。

    当一个线程执行到synchronized(Object)语句的时候,先检查Object对象的标志位,如果为0状态,表明已经有另外的线程正在执行synchronized包括的代码,那么这个线程将暂时阻塞,让出CPU资源,直到另外的线程执行完相关的同步代码,并将Object对象的标志位变为状态,这个线程的阻塞就被取消,线程能继续运行,该线程又将Object的标志位变为0状态,防止其它的线程再进入相关的同步代码块中。

    如果有多个线程因等待同一个对象的标志位面而处于阻塞状态时,当该对象的标志位恢复到1状态时,只会有一个线程能够进入同步代码执行,其它的线程仍处于阻塞的状态。

特别说明:

1、上面所说的标志位用术语讲就是对象锁,文件锁。数据库会有行锁、表锁等

2、synchronized(object)//object(就是对象锁)可以是任意类型对象

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值