Java多线程(1)

线程的简介

多线程是实现并发机制的一种有效的手段。进程和线程一样,都是实现并发的一个基本单位。只不过线程是比进程更小的执行单位,而且线程组成进程。
多线程机制可以同时运行多个程序模块,是程序运行的效率变得更高。

线程的状态

这里写图片描述
(1)创建状态:创建一个线程对象后,新的线程对象便处于新建状态,例如”Thread thread=new Thread();”
(2)就绪状态:调用start()方法,线程进入线程队列排队,等待CPU服务
(3)运行状态:就绪的线程被调用并且获取处理器资源时候,线程就进入了运行状态。此时,自动调用该线程对象的run()方法
(4)堵塞状态:调用sleep(),suspend()、wait()等方法。堵塞时,线程不能进入排队队列,只有将堵塞的原因被消除后,相爱难成才可以转入就绪状态
(5)死亡状态:线程调用stop()方法时候或者run()方法执行结束后


线程的实现

继承Thread实现

package com.thread.blog;

public class Demo1 extends Thread {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Demo1 d1=new Demo1();
        Demo1 d2=new Demo1();
        d1.setName("线程A");
        d2.setName("线程B");
        d1.start();
        d2.start();

    }
    public void run(){
        for(int i=1;i<11;i++){
            System.out.println("线程为"+Thread.currentThread().getName()+"执行了"+i);
        }
    }
}

继承Runnable接口

package com.thread.blog;

public class Demo2 implements Runnable{

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Demo2 d1=new Demo2();
        Demo2 d2=new Demo2();
        Thread t1=new  Thread(d1,"able1");
        Thread t2=new  Thread(d2,"able2");
        t1.start();
        t2.start();
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=1;i<11;i++){
            System.out.println("线程为"+Thread.currentThread().getName()+"执行了"+i);
        }
    }

}

线程的基本方法

Sleep与yield区别

package com.thread.blog;

/**
 * 总结:
 * (1)这里是展示Thread.sleep()方法,主要是休眠当前线程
 * (2)之后执行的线程,不分优先级的等级
 * (3)不会释放锁资源
 * @author DearMind-Hack
 *
 */
public class Demo3 implements Runnable{

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Demo3 Demo3=new Demo3();
        Thread  th=new  Thread(Demo3,"线程A");
        th.start();
        try {
            System.out.println(Thread.currentThread().getName());
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        System.out.println("子线程"+Thread.currentThread().getName());
    }

}

package com.thread.blog;

public class Demo4 implements Runnable{

    /**
     * (1)这个例子展示了,即使设置thread.setPriority(),每次执行的顺序也不一定
     * (2)yield()核心意思就是重新洗牌,当前线程变为就绪状态,然后新一轮的抢CPU开始了,
     *   区别:sleep()重新洗牌,不包括当前线程,而yield()包括而已
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Demo4 d1=new Demo4();
        Demo4 d2=new Demo4();
        Thread th1=new Thread(d1,"线程A");
        Thread th2=new Thread(d2,"线程B");
        th1.setPriority(Thread.MAX_PRIORITY);
        th2.setPriority(Thread.MIN_PRIORITY);
        th1.start();
        th2.start();
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=0;i<100;i++){
            Thread.yield();
            System.out.println("线程"+Thread.currentThread().getName()+"  "+i);
        }
    }

}

stop方法
可以用来终止一个线程,但是不安全,建议不要使用此方法来停止线程。
注: stop方法是立即停止当前线程, 这样停止的后果是导致stop后的语句无法执行, 有可能资源未释放. 列或者在同步块中调用此方法会导致同步数据会不完整. 所以需禁用此方法. 由于stop方法的特释性, 将不给出示范代码.
join()

package com.thread.blog;

public class Demo5 implements Runnable{
/**
 * join()方法
 * (1)从这个例子可以看到,0---9,是主线程和线程A并发的执行,当线程A调用
 *  join()方法后,仅仅执行线程A。只有当线程A执行完毕之后,才会执行主线程。
 */
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Demo5 d1=new Demo5();
        Thread th1=new Thread(d1,"线程A");
        th1.start();
        for(int i=0;i<50;i++){
            if(i>10){
                try {
                    th1.join();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        System.out.println("主函数执行"+"  "+i);
        }
    }

@Override
public void run() {
    // TODO Auto-generated method stub
        for(int i=0;i<50;i++){
            System.out.println(Thread.currentThread().getName()+"运行--》"+i);
        }
}

}

先执行当前线程,等该线程执行完毕之后,才能执行别的线程。
注: join函数为线程安全函数, 即同步函数. 也就是当ThreadJoin类的run用synchronized锁住时, t.join方法将得不到锁资源而等待更长的时间.


interrupt() 与isInterrupted()区别
(1)public boolean isInterrupted();
判断线程是否在活动,若果是返回true;否则返回false;
(2)interrupt()

package com.thread.blog;
/**
 * @author DearMind-Hack
 * (1)我对此方法的理解就是,叫醒一个正在阻塞的线程,返回就绪状态
 * 
 * */
public class Demo6 implements Runnable{

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Demo6 d1=new Demo6();
        Thread th1 =new Thread(d1,"线程A");
        th1.start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        th1.interrupt();
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        System.out.println("1、 进入run方法");
        try {
            Thread.sleep(10000);
            System.out.println("2、 已经完成休眠");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            System.out.println("3、休眠被终止");
                return;
        }
        System.out.println("4、 程序正常结束");
    }

}

线程的同步

一个多线程通过Runnable接口实现,意味着类的属性将被多个线程共享,这样一类就会造成资源的同步问题,例如:买票卖出负票。因此需要同步代码。
线程的同步分为:同步代码块和同步方法。
同步代码块

package com.thread.blog;
/**
 * (1)解决资源同步的问题,使用同步代码块或者同步方法的完成
 * (2)
 * */
public class Demo8 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MyThread my=new MyThread();
        Thread thread1=new Thread(my,"线程A");
        Thread thread2=new Thread(my,"线程B");
        Thread thread3=new Thread(my,"线程C");
        thread1.start();
        thread2.start();
        thread3.start();
    }

}
class MyThread implements Runnable{
    int ticket=10;
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=0;i<100;i++){
        synchronized (this) {
            if(ticket>0){
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println("线程名字为:"+Thread.currentThread().getName()+"出售了"+ticket--);
            }
        }
    }
    }

}

同步方法

package com.thread.blog;
/**
 * 
 * 
 * */
public class Demo9 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        TwoThread two=new TwoThread();
        Thread thread1=new Thread(two,"线程A");
        Thread thread2=new Thread(two,"线程B");
        Thread thread3=new Thread(two,"线程C");
        thread1.start();
        thread2.start();
        thread3.start();
    }

}
class TwoThread implements Runnable{
    int ticket=10;

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=0;i<100;i++){
            if(ticket>0){
                this.sale();
            }
        }
    }
   public  synchronized void sale(){
       try {
        Thread.sleep(300);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
        System.out.println("线程名字为:"+Thread.currentThread().getName()+"出售了"+ticket--);
   }
}

线程的死锁

两个线程都在等待对方先完成,造成了程序的停滞。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值