zoukankan      html  css  js  c++  java
  • 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 }


  • 相关阅读:
    C#脚本引擎 CS-Script 之(一)——初识
    系分过了,mark一下,就从这里开始吧
    Git.Framework 框架随手记-- 分享一个"比较垃圾"的项目
    Android--多选自动搜索提示
    Android--自动搜索提示
    Android--图片集
    Android--下拉框
    SQL Server 收缩日志
    Android--按钮点击事件
    Android--TextView 文字显示和修改
  • 原文地址:https://www.cnblogs.com/leon19870907/p/1961507.html
Copyright © 2011-2022 走看看