Java基础知识之多线程(2)

线程的休眠

使用方法:public static void sleep(long millis)throws InterruptedException{}

可见该方法有异常抛出,所以要进行异常的处理。

public class A implements Runnable {
    private String name;
    public A(String name) {
        super();
        this.name = name;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(500);//休眠
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("运行:" + name);
        }
    }
}

测试一下:

public class ATest {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        A mt1 = new A("线程1");
        A mt2 = new A("线程2");

        new Thread(mt1,"线程111").start();
        System.out.println(Thread.currentThread().getName());
        new Thread(mt2,"线程111").start();
    }
}

线程的优先级

public class MyThreadImplement implements Runnable {
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i < 5; i++) {
            try {
                Thread.sleep(500);//休眠
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            //得到当前的线程名称
            System.out.println(Thread.currentThread().getName());
        }
    }
}

测试类:

public class MyThreadImplementTest {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MyThreadImplement mt1 = new MyThreadImplement();

        Thread m1 = new Thread(mt1,"线程1");
        Thread m2 = new Thread(mt1,"线程2");
        Thread m3 = new Thread(mt1,"线程3");
        //使用setPriority()方法设置线程优先级
        //传入的参数是 Thread类中的常量,分别表示优先级最高,正常,最低
        m1.setPriority(Thread.MAX_PRIORITY);
        m2.setPriority(Thread.NORM_PRIORITY);
        m3.setPriority(Thread.MIN_PRIORITY);

        m1.start();m2.start();m3.start();
    }
}

线程的中断

调用interrupt()方法可以中断一个正在运行的线程!

线程的同步问题

看一个小例子:

public class TickThread implements Runnable {
    //模拟卖票,共5张
    private int tick = 5;
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i < 5; i++) {
            if(this.tick>0){
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println("卖票:"+tick--);
            }
        }
    }
}

测试类:

public class TickThreadTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        TickThread m = new TickThread();
        new Thread(m,"A").start();
        new Thread(m,"B").start();
        new Thread(m,"C").start();
    }
}

通过运行结果发现出现了异常。原因是代码中加入了休眠的操作,线程A正在休眠,线程B运行起来卖掉了当前线程A的票,A休眠结束后,继续卖票,出现了上面的情况。下面通过加入同步解决这个问题。

所谓同步,多个操作在同一个时间段只能有一个在进行,A线程在运行后,就不会

1)同步代码块实现同步

修改后的代码:

public class TickThread implements Runnable {

    private int tick = 5;
    @Override
    public void run() {
        // TODO Auto-generated method stub
        //synchronized声明同步代码块
        synchronized (this) {
            for (int i = 0; i < 5; i++) {
                if(this.tick>0){
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"运行"+tick--);
                }
            }
        }
    }
}

也可以把要同步的代码写成一个方法

修改后的代码:

public class TickThread implements Runnable {

    private int tick = 5;
    @Override
    public void run() {
        // TODO Auto-generated method stub
        //synchronized声明同步代码块
        fun();
    }
    public synchronized void fun(){
        for (int i = 0; i < 5; i++) {
            if(this.tick>0){
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"运行"+tick--);
            }
        }
    }
}

死锁问题

多个线程共享一个数据时需要进行同步,但过多的同步会产生死锁;

时间: 2024-08-02 05:41:13

Java基础知识之多线程(2)的相关文章

黑马程序员——Java基础知识之多线程协同

多线程协同 线程间的通讯:对资源的操作动作不同,比如说两个卡车一个拉煤一个装煤,但是他们共享了一个资源. 怎么样把这个资源拿出来?怎样把车装满?这个资源当然是一个类,他里面的组成元素就是对象!!现在我们就要有操作对象的思想了,用对象把这车装满,现在一车装一个对象. 等待唤醒机制: 用的不是sleep是wait.flag标记,这是两人沟通的方式.其实每个标记就要做一次等待或者notify,判断wait,改值notify.线程池.notify唤醒里面的线程,按顺序唤醒.wait和notify必须用在

java基础知识总结--多线程

1.扩展Java.lang.Thread类 1.1.进程和线程的区别: 进程:每个进程都有自己独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1~n个线程. 线程:同一类线程共享代码和数据空间,每一个线程有独立的运行栈和程序计数器,线程切换开销比较小. 进程和线程一样都分为五个阶段:创建.就绪.运行.阻塞.终止. 多进程是指操作系统能同时运行多个任务(程序). 多线程是指在同一个程序中有多个顺序流在执行. 1.2.在Java中要想实现多线程,有两种方法:继承Threa

Java基础知识之多线程(1)

1.认识线程 a) 对于线程来说,容易混淆的还有进程,我们用一个例子来区分它们,每次打开一个word文档,这就是一个进程,一个word中的拼写检查这是一个线程,再如每登陆一个QQ,这是一个进程,QQ中的每一个会话都是一个线程. b)对于只有一个CPU的电脑来说,一个时间点只有一个进程占用CPU 2.Java中如何实现线程 Java中实现多线程可以采用:继承Thread类,或,实现Runnable接口 a)继承Thread类,这个方式必须覆写run()方法 class 类名称 extends Th

JAVA基础知识之多线程——控制线程

join线程 在某个线程中调用其他线程的join()方法,就会使当前线程进入阻塞状态,直到被join线程执行完为止.join方法类似于wait, 通常会在主线程中调用别的线程的join方法,这样可以保证在所有的子线程执行结束之后在主线程中完成一些统一的步骤.下面是一个例子, package threads; public class JoinThread extends Thread { public JoinThread(String name) { super(name); } public

java基础知识回顾之java Thread类学习(八)--java多线程通信等待唤醒机制经典应用(生产者消费者)

 *java多线程--等待唤醒机制:经典的体现"生产者和消费者模型 *对于此模型,应该明确以下几点: *1.生产者仅仅在仓库未满的时候生产,仓库满了则停止生产. *2.消费者仅仅在有产品的时候才能消费,仓空则等待. *3.当消费者发现仓储没有产品可消费的时候,会唤醒等待生产者生产. *4.生产者在生产出可以消费的产品的时候,应该通知等待的消费者去消费. 下面先介绍个简单的生产者消费者例子:本例只适用于两个线程,一个线程生产,一个线程负责消费. 生产一个资源,就得消费一个资源. 代码如下: pub

java基础知识回顾之java Thread类学习(七)--java多线程通信等待唤醒机制(wait和notify,notifyAll)

1.wait和notify,notifyAll: wait和notify,notifyAll是Object类方法,因为等待和唤醒必须是同一个锁,不可以对不同锁中的线程进行唤醒,而锁可以是任意对象,所以可以被任意对象调用的方法,定义在Object基类中. wait()方法:对此对象调用wait方法导致本线程放弃对象锁,让线程处于冻结状态,进入等待线程的线程池当中.wait是指已经进入同步锁的线程,让自己暂时让出同步锁,以便使其他正在等待此锁的线程可以进入同步锁并运行,只有其它线程调用notify方

java基础知识回顾之java Thread类学习(六)--java多线程同步函数用的锁

1.验证同步函数使用的锁----普通方法使用的锁 思路:创建两个线程,同时操作同一个资源,还是用卖票的例子来验证.创建好两个线程t1,t2,t1线程走同步代码块操作tickets,t2,线程走同步函数封装的代码操作tickets,同步代码块中的锁我们可以指定.假设我们事先不知道同步函数用的是什么锁:如果在同步代码块中指定的某个锁(测试)和同步函数用的锁相同,就不会出现线程安全问题,如果锁不相同,就会发生线程安全问题. 看下面的代码:t1线程用的同步锁是obj,t2线程在操作同步函数的资源,假设不

java基础知识回顾之java Thread类学习(五)--java多线程安全问题(锁)同步的前提

这里举个例子讲解,同步synchronized在什么地方加,以及同步的前提: * 1.必须要有两个以上的线程,才需要同步. * 2.必须是多个线程使用同一个锁. * 3.必须保证同步中只能有一个线程在运行,锁加在哪一块代码 那么我们要思考的地方有:1.知道我们写的哪些是多线程代码 2.明确共享数据 3.明确多线程运行的代码中哪些语句是操作共享数据的.. 4.要确保使用同一个锁. 下面的代码:需求:两个存户分别往银行存钱,每次村100块,分三次存完. class bank{ private int

java基础知识回顾之java Thread类学习(四)--java多线程安全问题(锁)

上一节售票系统中我们发现,打印出了错票,0,-1,出现了多线程安全问题.我们分析为什么会发生多线程安全问题? 看下面线程的主要代码: @Override public void run() { // TODO Auto-generated method stub while(true){ if(ticket > 0){//当线程0被调起的时候,当执行到这条判断语句的时候,线程1被调起抢了CPU资源,线程0进入冻结状态. try { Thread.sleep(100);//中断当前活跃的线程,或者