java.多线程

来源:互联网 发布:数据精灵授权系统网站 编辑:程序博客网 时间:2024/04/29 11:28

1、进程、线程概念

进程:一个正在执行中的程序。每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者叫一个控制单元。
线程:就是进程中的一个独立的控制单元。线程在控制着进程的执行。
注:一个进程中至少有一个线程。

创建线程方式有两种
一:继承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的执行权也不能执行。线程加锁带来的弊端:要有锁对象,所以耗资源;要判断锁,所以效率稍减。 
   

二.同步函数
     public synchronized void method(Type args) {
                  需要被同步的语句; 
     }
     同步非静态函数用的锁是this。如果同步静态函数:所用的锁不是this,因为静态方法中不能出现this。用的是 类名.class是Class类型对象。 如果一个程序中有安全问题,使用同步时应注意:
     1、明确多线程运行代码(一般为run方法里调用的语句,以及其附带语句(调用了其它的方法))有哪些 2、明确共享数据为何 3、明确运行代码中有哪些语句操作共享数据

    使用同步还会出安全问题:此时定为同步的两个前提条件中的一个不满足所造成:1、必须有两个或两个以上的线程 2、必须是多个线程使用同一把锁。

多线程通信:

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();            }        }    } 




1 0
原创粉丝点击