java多线程学习(二)

来源:互联网 发布:windows程序设计pdf 编辑:程序博客网 时间:2024/05/16 18:13

java多线程学习(二)

标签(空格分隔): java 线程


  • java多线程学习二
      • 线程的优先级别
      • 线程的同步
      • 线程案例

线程的优先级别

java提供一个线程调度器来监控程序中启动后所有进入就绪状态的线程,线程调度器按照线程优先级执行线程。
线程优先级从1到10,用数字表示,从低到高,缺省的默认值为5

使用下面方法设置或者获取线程的优先级:

- int getPriority()- void setPriority(int num)

java 线程使用

/** *  */package com.frankstar.Thread;/** * @author frankstar * 线程优先级测试 */public class PriorityThread {    /**     * @param args     */    public static void main(String[] args) {        // TODO Auto-generated method stub        TestPriorityThread1 tpt1 = new TestPriorityThread1();        TestPriorityThread2 tpt2 = new TestPriorityThread2();        Thread t1 = new Thread(tpt1);        Thread t2 = new Thread(tpt2);//      t1.start();//      t2.start();  //先看未设置优先级的进程//      这里的优先级指的是执行一次的时间会较长即占据CPU时间片的时间会比较多        t1.setPriority(Thread.NORM_PRIORITY + 3);        t1.start();        t2.start();        System.out.println("t1的优先级为: " + t1.getPriority());    }}class TestPriorityThread1 implements Runnable {    @Override    public void run() {        // TODO Auto-generated method stub        for (int i = 0; i <= 5; i++) {            System.out.println("1st: " + i);        }    }}class TestPriorityThread2 implements Runnable {    @Override    public void run() {        // TODO Auto-generated method stub        for (int i = 0; i <= 5; i++) {            System.out.println("2st: " + i);        }    }}

线程的同步

- java中,引入了互斥锁的概念,保证共享数据操作的完整性。每一个对象都对应一个称为“互斥锁”的 标记,这个标记保证了在任何时刻,只能有一个线程访问此对象。- 关键字synchronized来与对象的互斥锁联系。当某个对象使用synchronized关键字修饰时,表示此对象在任何时刻,只能有一个线程访问。

synchronized案例

/** *  */package com.frankstar.Thread;/** * @author frankstar * 测试同步 * */public class SyncThread  implements Runnable{    Timer timer = new Timer();    /**     * @param args     */    public static void main(String[] args) {        // TODO Auto-generated method stub        SyncThread st = new SyncThread();        Thread t1 = new Thread(st);        Thread t2 = new Thread(st);        t1.setName("frank");        t2.setName("star");        t1.start();        t2.start();    }    @Override    public void run() {        // TODO Auto-generated method stub        timer.add(Thread.currentThread().getName());    }}class Timer {    private static int num = 0;    public /*synchronized */void add(String name) {        //在声明方法时加入synchronized表示执行这个方法的过程中当前对象被锁定        synchronized(this) {            //锁定当前对象            num++;            try {                Thread.sleep(1);            } catch (InterruptedException e) {                e.printStackTrace();            }            System.out.println(name + ": 你是第" + num + "个使用timer");        }    }}

线程锁定  解决线程死锁的问题最好只锁定一个对象,不要同时锁定两个对象

/** *  */package com.frankstar.Thread;/** * @author frankstar * 线程死锁问题 */public class LockThread implements Runnable {    public int flag = 1;    static Object o1 = new Object(), o2 = new Object();    /**     * @param args     */    public static void main(String[] args) {        // TODO Auto-generated method stub        LockThread lt1 = new LockThread();        LockThread lt2 = new LockThread();        lt1.flag = 1;        lt2.flag = 0;        Thread t1 = new Thread(lt1);        Thread t2 = new Thread(lt2);        t1.setName("frank");        t2.setName("star");        t1.start();        t2.start();    }    @Override    public void run() {        // TODO Auto-generated method stub        System.out.println(Thread.currentThread().getName() + " flag = " + flag);//      这里的两个if语句都将无法执行,因为已经造成了线程死锁的问题 //      flag=1这个线程在等待flag=0这个线程把对象o2的锁解开, //      而flag=0这个线程也在等待flag=1这个线程把对象o1的锁解开 //      然而这两个线程都不愿意解开锁住的对象,所以就造成了线程死锁的问题        if (flag == 1) {            synchronized (o1) { //锁定o1对象 只有o1这个线程对象执行完毕才会释放锁                try {                    Thread.sleep(500);                } catch (InterruptedException e) {                    e.printStackTrace();                }                synchronized(o2) {//                  前面已经锁住了对象o1,只要再能锁住o2,那么就能执行打印出1的操作了 //                  可是这里无法锁定对象o2,因为在另外一个flag=0这个线程里面已经把对象o1给锁住了 //                  尽管锁住o2这个对象的线程会每隔500毫秒睡眠一次,可是在睡眠的时候仍然是锁住o2不放的                    System.out.println("1");                }            }        }        if (flag == 0) {            synchronized (o2) { //锁定o2对象 只有o2这个线程对象执行完毕才会释放锁                try {                    Thread.sleep(500);                } catch (InterruptedException e) {                    e.printStackTrace();                }                synchronized(o1) {//                  前面已经锁住了对象o1,只要再能锁住o2,那么就能执行打印出1的操作了 //                  可是这里无法锁定对象o2,因为在另外一个flag=0这个线程里面已经把对象o1给锁住了 //                  尽管锁住o2这个对象的线程会每隔500毫秒睡眠一次,可是在睡眠的时候仍然是锁住o2不放的                    System.out.println("1");                }            }        }    }}

线程案例

/** *  */package com.frankstar.Thread;/** * @author frankstar * 生产者-消费者问题 * 1.共享数据的不一致性/临界资源的保护 * 2.java对象锁的概念 * 3.synchronized关键字/wait() notify() */public class ProducerConsumer {    /**     * @param args     */    public static void main(String[] args) {        // TODO Auto-generated method stub        SyncStack ss = new SyncStack();        Runnable p = new Producer(ss);        Runnable c = new Consumer(ss);        Thread p1 = new Thread(p);        Thread c1 = new Thread(c);        p1.start();        c1.start();    }}class SyncStack {    //支持多线程同步操作的堆栈实现    private int index = 0;    private char []data = new char[6];    public synchronized void push (char c) {        if (index == data.length) {            try {                this.wait();            } catch (InterruptedException e) {}        }        this.notify();        data[index] = c;        index++;    }    public synchronized char pop() {        if (index == 0) {            try {                this.wait();            } catch (InterruptedException e) {}        }        this.notify();        index--;        return data[index];    }}class Producer implements Runnable {    SyncStack stack;    public Producer (SyncStack s) {        stack = s;    }    @Override    public void run() {        // TODO Auto-generated method stub        for (int i = 0; i < 10; i++){            char c = (char)(Math.random()*26 + 'A');            stack.push(c);            System.out.println("生产: " + c);            try {                Thread.sleep((int)(Math.random()*1000));            } catch (InterruptedException e){            }        }    }}class Consumer implements Runnable {    SyncStack stack;    public Consumer(SyncStack s) {        stack = s;    }    @Override    public void run() {        // TODO Auto-generated method stub        for(int i = 0; i < 10; i++) {            char c = stack.pop();            System.out.println("消费: " + c);            try {                Thread.sleep((int) (Math.random()*1000));            } catch (InterruptedException e) {            }        }    }}
0 0
原创粉丝点击