多线程

本文详细介绍了Java多线程的基本概念,包括进程、线程的概念,如何创建线程,以及多线程的安全问题与解决方法。通过示例演示了多线程的创建与同步机制,帮助理解Java多线程的原理与应用。


  1、进程、线程概念

    进程:一个正在执行中的程序。每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者叫一个控制单元。
    线程:就是进程中的一个独立的控制单元。线程在控制着进程的执行。
    注:一个进程中至少有一个线程。
   【 J VM  启动时(通过命令行参数java启动)会有一个java.exe进程。该进程中至少有一个线程负责java程序的执行。而且这个线程运行的代码存在于main方法中。该线程称之为主线程。扩展:更加细节的说明jvm,其实jvm启动不止一个线程,还有负责垃圾回收机制的线程。】
  2、创建线程方式有两种
    第一种方式:继承Thread类。
   步骤:
        1,定义类继承Thread。

        2,复写Thread类中的run方法。

    目的:将自定义代码存储在run方法中,让线程通过start方法启动后来运行。
  3,调用线程的start方法,

    该方法两个作用:启动线程,调用run方法。

     线程创建:

public class MultiThread {  
  
    public static void main(String[] args) {  
        //创建并启动线程一  
        //new Demo().start();  
          
        //创建并启动线程二  
        new Thread(new Demo2()).start();  
          
        //主线程执行程序  
        for(int i=0; i<1000; i++) {  
            System.out.println(Thread.currentThread().getName() + ": The world " + i);  
        }  
    }  
}  
//定义线程的第一种方法:继承自Thread类  
class Demo extends Thread {  
    public void run() { //封装要运行的代码  
        for(int i=0; i<1000; i++) {  
            System.out.println(Thread.currentThread().getName() + ": Hello java " + i);  
        }  
    }  
}  
//定义线程的第二种方法:实现Runnable接口  
class Demo2 implements Runnable {  
    public void run() { //封装要运行的代码  
        for(int i=0; i<1000; i++) {  
            System.out.println(Thread.currentThread().getName() + ": Hello java " + i);  
        }  
    }  
}  
     实现方式和继承方式的区别?
     1、继承Thread,线程运行代码存放在Thread子类run方法中
        实现Runnable,线程运行代码存放在Runnable接口子类run方法中
     2、实现方式避免了java单继承的局限性。
     

     在定义线程类时,建议使用实现方式


     多窗口卖票示例:

public class SaleTicket {  
  
    public static void main(String[] args) {  
        Ticket t = new Ticket();  
        new Thread(t).start();  
        new Thread(t).start();  
        new Thread(t).start();  
        new Thread(t).start();  
    }  
  
}  
  
class Ticket implements Runnable {  
    private int ticket = 100;  
    public void run() {  
        while(ticket > 0) {  
            System.out.println(Thread.currentThread().getName() + "sale : " + ticket--);  
        }  
    }  
}  
        

     (若继承Thread,则Ticket的ticket属性应为static)

    多线程安全问题:     

    问题出现的状况:
     当多个线程在操作同一个共享数据时,一个线程的多条语句中只执行了一部分,CPU执行权即分配到了其它的线程中执行。导致共享数据错误。
     解决办法:
       单个线程在操作共享数据时,其它线程不能参与进来。
       java用的1、同步代码块来实现安全:

           synchronized(对象) {

                       需要被同步的语句;
          }
    对象如同锁,没有锁的线程就算取得了CPU的执行权也不能执行。
    线程加锁带来的弊端:要有锁对象,所以耗资源;要判断锁,所以效率稍减。 
   

   2、同步函数
       public synchronized void method(Type args) {
                  需要被同步的语句; 
       }

     同步非静态函数用的锁是this。如果同步静态函数:所用的锁不是this,因为静态方法中不能出现this。用的是 类名.class是Class类型对象。 如果一个程序中有安全问题,使用同步时应注意:

     1、明确多线程运行代码(一般为run方法里调用的语句,以及其附带语句(调用了其它的方法))有哪些 2、明确共享数据为何 3、明确运行代码中有哪些语句操作共享数据
 
    使用同步还会出安全问题:此时定为同步的两个前提条件中的一个不满足所造成:1、必须有两个或两个以上的线程 2、必须是多个线程使用同一把锁。

     多线程通信:

     

<span style="color:#666666;">public class ThreadCommunication{  
  
    public static void main(String[] args) {  
        Res r = new Res();  
        new Thread(new Input(r)).start();  
        new Thread(new Output(r)).start();  
    }  
  
}  
//共享资源  
class Res {  
    private String name;  
    private String sex;  
    private boolean flag = false;  
    //设置方法  
    public synchronized void set(String name, String sex){  
        if(flag)//flag=true表示设置过的还未打印,有数据则等待  
            try{this.wait();}catch(InterruptedException e){e.printStackTrace();}  
        this.name = name;  
        this.sex = sex;  
        flag = true;  
        this.notify();  
    }  
    //打印方法  
    public synchronized void out(){  
        if(!flag)  
            try{this.wait();}catch(InterruptedException e){e.printStackTrace();}  
        System.out.println(name + ".........." + sex);  
        flag = false;  
        this.notify();  
    }  
}  
//输入线程  
class Input implements Runnable{  
    private Res r;  
    Input(Res r) {  
        this.r = r;  
    }  
    public void run() {  
        int x = 0;  
        while(true) {  
            if(x==0) {  
                r.set("lisi", "man");                     
            }  
            else {  
                r.set("丽丽", "女女女女");                      
            }  
            x = (x+1)%2;//控制x在0和1之间不断交替,从而让设置的内容不同。  
        }  
    }  
}  
//输出线程  
class Output implements Runnable{  
    private Res r;  
    Output(Res r) {  
        this.r = r;  
    }  
    public void run() {  
        while(true) {  
            r.out();  
        }  
    }  
}  </span>

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值