java学习---多线程

来源:互联网 发布:交友软件机器人 编辑:程序博客网 时间:2024/06/05 02:13

一、线程和进程的概念
进程:一个计算机程序的运行实例,包含了需要执行的指令;有自己的独立地址空间,包含程序内容和数据;不同进程的地址空间是互相隔离的;进程拥有各种资源和状态信息,包括打开的文件、子进程和信号处理。
线程:表示程序的执行流程,是CPU调度执行的基本单位;线程有自己的程序计数器、寄存器、堆栈和帧。同一进程中的线程共用相同的地址空间,同时共享进进程锁拥有的内存和其他资源。
二、
1.创建线程
在Java中创建线程有三种方法:使用Thread类和使用Runnable接口还有一种使用线程池。在使用Runnable接口时需要建立一个Thread实例。因此,无论是通过Thread类还是Runnable接口建立线程,都必须建立Thread类或它的子类的实例。Thread构造函数:
public Thread( );
public Thread(Runnable target);
public Thread(String name);
public Thread(Runnable target, String name);
public Thread(ThreadGroup group, Runnable target);
public Thread(ThreadGroup group, String name);
public Thread(ThreadGroup group, Runnable target, String name);
public Thread(ThreadGroup group, Runnable target, String name, long stackSize);
方法一:继承Thread 类覆盖Run()方法

public class ThreadDemo1 {     public static void main(String[] args){         Demo d = new Demo();         d.start();         for(int i=0;i<60;i++){             System.out.println(Thread.currentThread().getName()+i);         }     } } class Demo extends Thread{     public void run(){         for(int i=0;i<60;i++){             System.out.println(Thread.currentThread().getName()+i);         }     } }

方法二:

public class ThreadDemo2 {    public static void main(String[] args){        Demo2 d =new Demo2();        Thread t = new Thread(d);        t.start();        for(int x=0;x<60;x++){            System.out.println(Thread.currentThread().getName()+x);        }    }}class Demo2 implements Runnable{    public void run(){        for(int x=0;x<60;x++){            System.out.println(Thread.currentThread().getName()+x);        }    }}

2、线程的状态(生命周期)

线程生命周期

已经废弃的方法:stop、suspend、resume、destroy,这些方法在实现上时不安全的。
线程的状态:new、Runnable、blocked、waiting、timed_waiting(有超时的等待)、terminated。
a、方法sleep()进入的阻塞状态,不会释放对象的锁(即大家一起睡,谁也别想执行代码),所以不要让sleep方法处在synchronized方法或代码块中,否则造成其他等待获取锁的线程长时间处于等待。
b、方法join()则是主线程等待子线程完成,再往下执行。例如main方法新建两个线程A和B
c、方法interrupt(),向被调用的对象线程发起中断请求。如线程A通过调用线程B的d的interrupt方法来发出中断请求,线程B来处理这个请求,当然也可以忽略,这不是必须的。Object类的wait()、Thread类的join()和sleep方法都会抛出受检异常java.lang.InterruptedException,通过interrupt方法中断该线程会导致线程离开等待状态。对于wait()调用来说,线程需要重新获取监视器对象上的锁之后才能抛出InterruptedException异常,并致以异常的处理逻辑。
可以通过Thread类的isInterrupted方法来判断是否有中断请求发生,通常可以利用这个方法来判断是否退出线程(类似上面的volatitle修饰符的例子);
Thread类还有个方法Interrupted(),该方法不但可以判断当前线程是否被中断,还会清楚线程内部的中断标记,如果返回true,即曾被请求中断,同时调用完后,清除中断标记。
d、如果一个线程在某个对象的等待池,那么notify和interrupt 都可以使该线程从等待池中被移除。如果同时发生,那么看实际发生顺序。如果是notify先,那照常唤醒,没影响。如果是interrupt先,并且虚拟机选择让该线程中断,那么即使nofity,也会忽略该线程,而唤醒等待池中的另一个线程。
e、yield(),尝试让出所占有的CPU资源,让其他线程获取运行机会,对操作系统上的调度器来说是一个信号,不一定立即切换线程。(在实际开发中,测试阶段频繁调用yeid方法使线程切换更频繁,从而让一些多线程相关的错误更容易暴露出来)。

0 0
原创粉丝点击