java线程详解二

线程的优先级

线程调度:按照特定的机制为线程分配CPU的时间片段的行为,java程序再运行的时候,由java虚拟机负责线程的调度

线程调度的实现方式:1、分时调度,2、抢占式调度

分时调度:指让所有线程轮流获取CPU的使用权,并为每个线程平均分配CPU的时间片段

抢占式调度:指选择优先级较高的线程执行,如果所有的线程优先级相同,则会随机选择一个线程执行,java虚拟机正是采用这个调度模式。

线程优先级范例一:

 1 public class ThreadTest5 {
 2 
 3     public static void main(String[] args) {
 4 
 5         Thread th = new Thread(new Runnable() {
 6             @Override
 7             public void run() {
 8 
 9                 for (int i = 0; i <100 ; i++) {
10 
11                     System.out.println(Thread.currentThread().getName());
12                 }
13 
14 
15             }
16         });
17         th.setPriority(1);//设置该线程的优先级
18         th.start();//开启这个线程,并执行run方法
19         System.out.println(th.getPriority());//获取该线程的优先级
20 
21 
22         Thread th2 = new Thread(new Runnable() {
23             @Override
24             public void run() {
25 
26                 for (int i = 0; i <100 ; i++) {
27 
28                     System.out.println(Thread.currentThread().getName());
29                 }
30 
31 
32             }
33         });
34         th2.setPriority(10);//设置该线程的优先级
35         th2.start();//开启这个线程,并执行run方法
36         System.out.println(th2.getPriority());//获取该线程的优先级
37 
38 
39 
40 
41     }
42 }

注意:自定义的线程和main方法主线程的优先级默认都是5,线程的优先级用数据表示,范围1~10

线程同步

什么是线程安全:多线程应用程序同时访问共享对象时,由于线程之间相互抢占CPU的控制权,会造成一个线程夹在另一个线程的执行过程中运行,会造成错误的执行的过程

synchronized关键字:确保共享对象只能被一个线程访问,这种机制称为线程同步或者线程互斥,java中的线程同步是基于对象锁的概念。

synchronized关键字使用范例

 1 public class ThreadTest6 {
 2 
 3     public static void main(String[] args) {
 4 
 5         maipiao maipiao = new maipiao();
 6 
 7         Thread t1 = new Thread(maipiao,"学生");
 8         Thread t2 = new Thread(maipiao,"白领");
 9         Thread t3 = new Thread(maipiao,"工人");
10 
11         t1.start();
12         t2.start();
13         t3.start();
14 
15     }
16 
17 
18 
19 
20 }
21 
22 /**
23  *定义一个线程类
24  */
25 class maipiao implements Runnable{
26 
27     private Integer ticket = 100;//定义100张票
28     private Boolean state = true;
29     @Override
30     public void run() {
31 
32         while (state){
33             function();
34         }
35 
36     }
37 
38     /**
39      * 买票的实现方法
40      *synchronized关键字:加在方法上该方法就是一个同步方法,在某一个时间片段只能由一个线程方法该方法
41      */
42 
43     public /*synchronized*/ void function(){
44 
45         //也可以用同步代码块的方式保持同步
46         synchronized (this){
47             if(ticket<=0){
48                 state=false;
49                 return;
50             }
51 
52             try {
53                 Thread.sleep(1000);//让线程睡眠1秒
54             } catch (InterruptedException e) {
55                 e.printStackTrace();
56             }
57 
58             if(state){
59                 System.out.println(Thread.currentThread().getName()+"-抢到了第"+ticket--+"张票");
60             }
61         }
62 
63 
64     }
65 }

同步方法和同步代码块的作用是一样的,只是控制的范围不一样,范围越大,性能越差,所以一般使用同步代码块来保持线程同步

线程之间的通信

列举3个重要的方法:均是java.lang.Object中的方法,只能在同步方法或者同步代码块中使用,否则会抛出异常

wait()方法:中断方法的执行,使当前线程等待,暂时让出CPU的使用权,并允许其他线程使用该同步方法。

notify()方法:唤醒单个使用同步方法等待的线程

notifyall()方法:唤醒所有使用同步方法等待的线程

生产者消费者问题

 

 1 /*    范例名称:生产者--消费者问题
 2  *     源文件名称:ProducerConsumer.java
 3  *    要  点:
 4  *        1. 共享数据的不一致性/临界资源的保护
 5  *        2. Java对象锁的概念
 6  *        3. synchronized关键字/wait()及notify()方法
 7  */
 8 
 9 public class ProducerConsumer {
10     public static void main(String args[]){
11         SyncStack stack = new SyncStack();
12         Runnable p=new Producer(stack);
13         Runnable c = new Consumer(stack);
14         Thread p1 = new Thread(p);
15         Thread c1 = new Thread(c);
16 
17         p1.start();
18         c1.start();
19     }
20 }
21 
22 
23 class SyncStack{  //支持多线程同步操作的堆栈的实现
24     private int index = 0;
25     private char[] data = new char[6];
26 
27     public synchronized void push(char c){
28         if(index == data.length){
29             try{
30                 this.wait();
31             }catch(InterruptedException e){}
32         }
33         this.notify();
34         data[index] = c;
35         index++;
36     }
37 
38     public synchronized char pop(){
39         if(index ==0){
40             try{
41                 this.wait();
42             }catch(InterruptedException e){}
43         }
44         this.notify();
45         index--;
46         return data[index];
47     }
48 }
49 
50 
51 class  Producer implements Runnable{
52     SyncStack stack;
53     public Producer(SyncStack s){
54         stack = s;
55     }
56     public void run(){
57         for(int i=0; i<20; i++){
58             char c =(char)(Math.random()*26+'A');
59             stack.push(c);
60             System.out.println("produced:"+c);
61             try{
62                 Thread.sleep((int)(Math.random()*1000));
63             }catch(InterruptedException e){
64             }
65         }
66     }
67 }
68 
69 
70 class Consumer implements Runnable{
71     SyncStack stack;
72     public Consumer(SyncStack s){
73         stack = s;
74     }
75     public void run(){
76         for(int i=0;i<20;i++){
77             char c = stack.pop();
78             System.out.println("消费:"+c);
79             try{
80                 Thread.sleep((int)(Math.random()*1000));
81             }catch(InterruptedException e){
82             }
83         }
84     }
85 }

 

posted @ 2019-05-21 10:33  子爵号  阅读(163)  评论(0编辑  收藏  举报