欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

黑马程序员_java08_多线程

程序员文章站 2022-07-15 16:34:05
...
转载于:http://www.itxuexiwang.com/plus/view.php?aid=148
线程是程序中可以并行执行的任务。 java运行系统总是选当前优先级最高的处于就绪状态的线程来执行。如果几个就绪线程有相同的优先级,将会用时间片方*流分配处理机。 进程与线程的区别 进程属于一个独立的运行程序,线程是程序里面的一个分支。许多个线程组成一个程序的运行。 创建线程的两种方式 (1)线程类是由Thread类及其子类表示的,继承Run()方法定义了线程执行时的任务体,定义一个继承于Thread的线程类覆盖run()方法。 (2)任何实现接口Runnable的对象都可以作为一个线程的目标对象,类Thread本身也实现了接口Runnable,接口中的run()方法需要实现为线程执行的任务体。 (3)可以利用Thread的类方法currentThread()获得当前执行线程的信息。 方法一: public class Person extends Thread{ public Person(String name){ this.name=name; } @Override public void run(){ super.run(); } } 1 2 3 4 5 6 7 8 9 方法二: class Res { private String name; private String sex; boolean flag=false; public synchronized void set(String name,String sex) { if (flag) { try{this.wait();} catch (Exception e){} } this.name=name; this.sex=sex; flag=true; this.notify(); } public synchronized void out() { if (!flag) { try { this.wait(); } catch (Exception e) { } System.out.println("name="+name+"\t"+"sex="+sex); flag=false; this.notify(); } } } class Input implements Runnable { private Res r; int x=0; Input(Res r) { this.r=r; } public void run() { while (true) { if (x==0) { r.set("Mike","man"); } else { r.set("丽丽","女女"); } x=(x+1)%2; } } } class Output implements Runnable { private Res r; Output(Res r) { this.r=r; } public void run() { while (true) { r.out(); } } } class ThreadDemo { public static void main(String[] args) { Res r=new Res(); new Thread(new Output(r)).start(); new Thread(new Input(r)).start(); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 与Thread类相比,利用实现Runnable接口定义线程类在使用中更加灵活。这时,实现接口Runnable的类可以继承其他父类。如果只要重写run() 方法,而不是重写其他Thread方法,那么应使用Runnable接口。 线程的同步 wait() 方法 当对象执行该方法时,正在访问此对象的线程将被阻塞,暂时停止运行,直到其他线程执行这个对象的notify()和notifyAll()方法,直到唤醒为止。唤醒后的线程应该继续对导致该线程被提醒的条件进行测试。 每个java对象都有一个锁,每个锁只有一把钥匙。 通常对象都没上锁,也没有在乎这件事。 但是如果对象有同步化的方法,则线程只能在取得钥匙的情况下进入线程。也就是说并没有其他线程已经进入的情况下才能进入。 线程的死锁 在多线程访问时,需要避免一些死锁。死锁往往是因为多线程共享资源,而共享资源的加锁顺序不当导致的。 守护线程 java语言中的线程有两种:守护线程和用户线程。用户线程都是在线程中创建。而守护线程有两种源,一种是虚拟机内部创建的线程,如垃圾回收的线程就守护线程;另一种是创建Thread对想后,可以调用Thread类的setDeamon的方法。指定该线程是守护线程。 守护线程是为用户线程服务的,当应用中没有任何用户线程运行时,虚拟机将退出。 class StopThread implements Runnable { private boolean flag=true; public synchronized void run() { while (flag) { try { wait(); } catch (InterruptedException e) { System.out.println(Thread.currentThread().getName()+"InterruptedException"); flag=false; } System.out.println(Thread.currentThread().getName()+"run running"); } } public void changeFlag() { flag=false; } } class StopThreadDemo { public static void main(String[] args) { StopThread st=new StopThread(); Thread t=new Thread(st); Thread t1=new Thread(st); t.setDaemon(true); t1.setDaemon(true); t.start(); t1.start(); int num=0; while (true) { if (num++==70) { break; } System.out.println(Thread.currentThread().getName()+"running............."+num); } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 使用synchronized这个关键字修饰符可以防止两个线程同时进入一个对象的同一个方法。 对象就算是有多个同步化的方法,也还是一个锁。一旦某个线程进入该对象的同步化方法,其他线程就无法进入该对象上的任何同步化线程