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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值