Java多线程复习

一、线程的基本概念
简单的说:线程就是一个程序里不同的执行路径
在同一个时间点上cpu只会有一个线程在执行
Java里的多线程是通过java.lang.Thread类来实现的
每个线程都拥有自己独立的方法栈空间

二、java线程的创建和启动
第一种
 定义线程类实现Runnable接口
 Thread myThread = new Thread(target) //target为Runnable接口类型
 Runnable中只有一个方法:
 public void run();用以定义线程运行体
第二种
 可以定义一个Thread的子类并重写其run方法:
  clas MyThread extends Thread{
   public void run(){}
  }
线程类必须通过执行Thread的start()方法启动一个新的线程
如果调用run()方法是属于方法的调用,不会启动一个新的线程
推荐使用第一种方式创建线程,使用接口较为灵活

二、线程状态装换
调用线程start()方法时,线程进入就绪状态,Cpu分配时间片,线程进入运行状态
时间片结束,run()方法未执行完,线程进入阻塞状态。

三、线程控制基本方法
 isAlive() //判断线程是否还“活着”,即线程是否还未终止
 getPriority() //获得线程的优先级数值
 setPriority() //设置线程的优先级指数
 Thread.sleep() //静态方法,将当前线程睡眠指定毫秒数
 join()  //调用某线程的该方法,将当前线程与该线程合并,即等待该线程结束,再回复当前线程的运行。
 yield()  //让出CPU,当前线程进入就绪状态等待调度,并执行其它线程。
 interrupt() //中断线程
 wait()  //当前线程进入对象的wait pool
 notify()/all //唤醒对象的wait pool中的一个或所有等待线程

四、sleep方法
 Thread的静态方法
 public static void sleep(long millis)throws InterruptedException //必须对异常进行捕捉
 Thread.currentThread();  //得到当前线程

五、一种让线程退出的方式(interrupt方法)。 

1 import java.util.*;
2  public class TestInterrupt{
3 public static void main(String[] args){
4 MyThread t = new MyThread();
5 t.start();
6 try{Thread.sleep(10000);}
7 catch(InterruptedException i){}
8 t.interrupt();
9 }
10 }
11
12  class MyThread extends Thread{
13 public void run(){
14 while(true){
15 try{
16 System.out.println("------"+new Date()+"-----");
17 Thread.sleep(1000);//主线程sleep10秒结束将interrupt该线程的输出
18 }catch(InterruptedException i){
19 return;
20 }
21 }
22 }
23 }

六、join和yield方法 
 t.join(); //t的run()方法执行完才会继续执行当前线程方法体

 t.yield(); //暂停当前正在执行的线程对象,并执行其他线程。方法为静态

1 public class TestYield {
2 public static void main(String[] args) {
3 MyThread3 t1 = new MyThread3("t1");
4 MyThread3 t2 = new MyThread3("t2");
5 t1.start(); t2.start();
6 }
7 }
8  class MyThread3 extends Thread {
9 MyThread3(String s){super(s);}
10 public void run(){
11 for(int i =1;i<=100;i++){
12 System.out.println(getName()+": "+i);
13 if(i%10==0){
14 yield();
15 }
16 }
17 }
18 }

注意:yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。所以上面的程序不会实现2个线程交替每次输出10个数字!

七、线程优先级别 
 线程的优先级用数字表示,范围从1到10,一个线程的缺省优先级为5.
 Thread.MAX_PRIORITY=1
 Thread.MIN_PRIORITY=10
 Thread.NORM_PRIORITY=5
 例:t.setPriority(Thread.NORM_PRIORITY+3);

★八、线程同步
 1.同步代码块
 synchronized(this){  //在执行代码块过程中,不会被其他线程打断
  ...  
 }
 public sunchronized void method //执行此方法时,当前对象被锁定
 在Java语言中,引入了对象互斥锁的概念,保证共享数据操作的完整性,每个对象 都对应一个可称为"互斥锁"的标记,这个标记保证在任一时刻,只能有一个线程访 问该对象。

2.生产者、消费者model

1 /*@src http://eric-619.javaeye.com/blog/693681
2 * 生产者消费者问题其含义就是先生产出了产品,才能拉出去让消费者购买
3 * 一、重点:
4 * 1、多个线程数据共享区域化思想!---源于多线程的近亲思想!!(类似于静态变量的改变)
5 * (如栈内存和对内存,还有当做栈内存和堆内存,如数组和基本数据类型,只要是访问的同一个。)
6 * 2、生产者消费者
7 *
8 * 二、synchronized加锁:
9 *
10  */
11
12
13  public class ProCon{ //主方法
14  
15  public static void main(String[] args){
16 SyncStack stack = new SyncStack();
17 Consumer p = new Consumer(stack);
18 Producer c = new Producer(stack);
19
20
21  new Thread(p).start();
22  new Thread(c).start();
23 }
24 }
25
26  class Producer implements Runnable{ //生产者
27   private SyncStack stack;
28
29 public Producer(SyncStack stack){
30 this.stack = stack;
31 }
32
33 public void run(){
34 for (int i = 0; i < stack.pro().length; i++){
35 String product = "产品"+i;
36 stack.push(product);
37 System.out.println("生产了: "+product);
38 try{
39 Thread.sleep(200);
40 }catch(InterruptedException e)
41 {
42 e.printStackTrace();
43 }
44 }
45 }
46 }
47
48  class Consumer implements Runnable{ //消费者
49   private SyncStack stack;
50
51 public Consumer(SyncStack stack) {
52 this.stack = stack;
53 }
54
55 public void run(){
56 for(int i = 0; i < stack.pro().length; i++){
57 String product = stack.pop();
58 System.out.println("消费了: "+product);
59 try{
60 Thread.sleep(1000);
61 }catch(InterruptedException e){
62 e.printStackTrace();
63 }
64 }
65 }
66 }
67
68  class SyncStack{ // 此类是(本质上:共同访问的)共享数据区域
69 private String[] str = new String[10];
70 private int index;
71
72 public synchronized void push(String sst){ //供生产者调用
73 if(index == sst.length()){
74 try{
75 wait();
76 }catch(InterruptedException e){
77 e.printStackTrace();
78 }
79 }
80 this.notify(); //唤醒在此对象监视器上等待的单个线程
81 str[index] = sst;
82 index++;
83 }
84
85 public synchronized String pop(){ //供消费者调用
86 if(index == 0){
87 try{
88 wait();
89 }catch (InterruptedException e){
90 e.printStackTrace();
91 }
92 }
93 notify();
94 index--;
95 String product = str[index];
96 return product;
97 }
98
99 public String[] pro(){ //就是定义一个返回值为数组的方法,返回的是一个String[]引用
100 return str; //这是一个String[]引用
101 }
102 }


原文地址:https://www.cnblogs.com/leon19870907/p/1961507.html