黑马程序员_多线程

来源:互联网 发布:mac onedrive 打不开 编辑:程序博客网 时间:2024/06/10 03:44
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------

线程简述

/*

进程:正在进行中的程序(直译)。

线程:就是进程中一个负责程序执行的控制单元(执行路径),

一个进程中可以多执行路径,称之为多线程。

一个进程中至少要有一个线程。

开启多个线程是为了同时运行多部分代码。

每一个线程都有自己运行的内容。这个内容可以称为线程要执行的任务。

多线程好处:解决了多部分同时运行的问题。

多线程的弊端:线程太多回到效率的降低。

其实应用程序的执行都是cpu在做着快速的切换完成的,这个切换是随机的。

JVM启动时就启动了多个线程,至少有两个线程可以分析的出来。

1,执行main函数的线程,

该线程的任务代码都定义在main函数中。

2,负责垃圾回收的线程。

 */

class Demo extends Object {

public void finalize() {

System.out.println("demo ok");

}

}

 

class ThreadDemo {

public static void main(String[] args) {

new Demo();

new Demo();

new Demo();

System.gc();

System.out.println("Hello World!");

}

}

 

创建线程方法之一继承thread

/*

如何创建一个线程呢?

创建线程方式一:继承Thread类。

步骤:

1,定义一个类继承Thread类。

2,覆盖Thread类中的run方法。

3,直接创建Thread的子类对象创建线程。

4,调用start方法开启线程并调用线程的任务run方法执行。

可以通过Thread的getName获取线程的名称  Thread-编号(从0开始)

主线程的名字就是main。

 */

class Demo extends Thread {

private String name;

 

Demo(String name) {

super(name);

// this.name = name;

}

 

public void run() {

for (int x = 0; x < 10; x++) {

// for(int y=-9999999; y<999999999; y++){}

System.out.println(name + "....x=" + x + ".....name="

+ Thread.currentThread().getName());

}

}

}

 

class ThreadDemo2 {

public static void main(String[] args) {

/*

 * 创建线程的目的是为了开启一条执行路径,去运行指定的代码和其他代码实现同时运行。 而运行的指定代码就是这个执行路径的任务。

 * jvm创建的主线程的任务都定义在了主函数中。 而自定义的线程它的任务在哪儿呢?

 * Thread类用于描述线程,线程是需要任务的。所以Thread类也对任务的描述。

 * 这个任务就通过Thread类中的run方法来体现。也就是说,run方法就是封装自定义线程运行任务的 函数。

 * run方法中定义就是线程要运行的任务代码。 开启线程是为了运行指定代码,所以只有继承Thread类,并复写run方法。

 * 将运行的代码定义在run方法中即可。

 */

//

// Thread t1 = new Thread();

Demo d1 = new Demo("旺财");

Demo d2 = new Demo("xiaoqiang");

d1.start();// 开启线程,调用run方法。

d2.start();

System.out.println("over...." + Thread.currentThread().getName());

}

}

 

多线程典型案例之银行存钱

/*

需求:储户,两个,每个都到银行存钱每次存100,,共存三次。

 */

class Bank {

private int sum;

 

// private Object obj = new Object();

public synchronized void add(int num)// 同步函数

{

// synchronized(obj)

// {

sum = sum + num;

// -->

try {

Thread.sleep(10);

catch (InterruptedException e) {

}

System.out.println("sum=" + sum);

// }

}

}

 

class Cus implements Runnable {

private Bank b = new Bank();

 

public void run() {

for (int x = 0; x < 3; x++) {

b.add(100);

}

}

}

 

class BankDemo {

public static void main(String[] args) {

Cus c = new Cus();

Thread t1 = new Thread(c);

Thread t2 = new Thread(c);

t1.start();

t2.start();

}

}

 

死锁常见情形之同步嵌套

/*

 死锁:常见情景之一:同步的嵌套。

 */

class Ticket implements Runnable {

private int num = 100;

Object obj = new Object();

boolean flag = true;

 

public void run() {

if (flag)

while (true) {

synchronized (obj) {

show();

}

}

else

while (true)

this.show();

}

 

public synchronized void show() {

synchronized (obj) {

if (num > 0) {

try {

Thread.sleep(10);

catch (InterruptedException e) {

}

System.out.println(Thread.currentThread().getName()

".....sale...." + num--);

}

}

}

}

 

class DeadLockDemo {

public static void main(String[] args) {

Ticket t = new Ticket();

// System.out.println("t:"+t);

Thread t1 = new Thread(t);

Thread t2 = new Thread(t);

t1.start();

try {

Thread.sleep(10);

catch (InterruptedException e) {

}

t.flag = false;

t2.start();

}

}

 

典型死锁案例(synchronized同步嵌套)

class Test implements Runnable {

private boolean flag;

 

Test(boolean flag) {

this.flag = flag;

}

 

public void run() {

if (flag) {

while (true)

synchronized (MyLock.locka) {

System.out.println(Thread.currentThread().getName()

"..if locka....");

synchronized (MyLock.lockb) {

System.out.println(Thread.currentThread().getName()

"..if lockb....");

}

}

else {

while (true)

synchronized (MyLock.lockb) {

System.out.println(Thread.currentThread().getName()

"..else lockb....");

synchronized (MyLock.locka) {

System.out.println(Thread.currentThread().getName()

"..else locka....");

}

}

}

}

}

 

class MyLock {

public static final Object locka = new Object();

public static final Object lockb = new Object();

}

 

class DeadLockTest {

public static void main(String[] args) {

Test a = new Test(true);

Test b = new Test(false);

Thread t1 = new Thread(a);

Thread t2 = new Thread(b);

t1.start();

t2.start();

}

}

 

多线程下的单例

/*

 多线程下的单例

 */

//饿汉式

class Single {

private static final Single s = new Single();

 

private Single() {

}

 

public static Single getInstance() {

return s;

}

}

 

// 懒汉式

/*

 * 加入同步为了解决多线程安全问题。 加入双重判断是为了解决效率问题。

 */

class Single {

private static Single s = null;

 

private Single() {

}

 

public static Single getInstance() {

if (s == null) {

synchronized (Single.class) {

if (s == null)

// -->0 -->1

s = new Single();

}

}

return s;

}

}

 

class SingleDemo {

public static void main(String[] args) {

System.out.println("Hello World!");

}

}

 

 

静态同步凼数的锁

/*

 静态的同步函数使用的锁是该函数所属字节码文件对象,

 可以用  getClass方法获取,也可以用当前类名.class  表示。

 */

class Ticket implements Runnable {

private static int num = 100;

// Object obj = new Object();

boolean flag = true;

 

public void run() {

// System.out.println("this:"+this.getClass());

if (flag)

while (true) {

synchronized (Ticket.class)// (this.getClass())

{

if (num > 0) {

try {

Thread.sleep(10);

catch (InterruptedException e) {

}

System.out.println(Thread.currentThread().getName()

".....obj...." + num--);

}

}

}

else

while (true)

this.show();

}

 

public static synchronized void show() {

if (num > 0) {

try {

Thread.sleep(10);

catch (InterruptedException e) {

}

System.out.println(Thread.currentThread().getName()

".....function...." + num--);

}

}

}

 

class StaticSynFunctionLockDemo {

public static void main(String[] args) {

Ticket t = new Ticket();

// Class clazz = t.getClass();

//

// Class clazz = Ticket.class;

// System.out.println("t:"+t.getClass());

Thread t1 = new Thread(t);

Thread t2 = new Thread(t);

t1.start();

try {

Thread.sleep(10);

catch (InterruptedException e) {

}

t.flag = false;

t2.start();

}

}

 

同步凼数&同步代码块的锁

/*

 同步函数的使用的锁是this;

 同步函数和同步代码块的区别: 

 同步函数的锁是固定的this。

 同步代码块的锁是任意的对象。

 建议使用同步代码块。

 */

class Ticket implements Runnable {

private int num = 100;

// Object obj = new Object();

boolean flag = true;

 

public void run() {

// System.out.println("this:"+this);

if (flag)

while (true) {

synchronized (this) {

if (num > 0) {

try {

Thread.sleep(10);

catch (InterruptedException e) {

}

System.out.println(Thread.currentThread().getName()

".....obj...." + num--);

}

}

}

else

while (true)

this.show();

}

 

public synchronized void show() {

if (num > 0) {

try {

Thread.sleep(10);

catch (InterruptedException e) {

}

System.out.println(Thread.currentThread().getName()

".....function...." + num--);

}

}

}

 

class SynFunctionLockDemo {

public static void main(String[] args) {

Ticket t = new Ticket();

// System.out.println("t:"+t);

Thread t1 = new Thread(t);

Thread t2 = new Thread(t);

t1.start();

try {

Thread.sleep(10);

catch (InterruptedException e) {

}

t.flag = false;

t2.start();

}

}

 

创建线程方法之二即实现Runnable接口

/*

 创建线程的第一种方式:继承Thread类。

 创建线程的第二种方式:实现Runnable接口。

 1,定义类实现Runnable接口。

 2,覆盖接口中的run方法,将线程的任务代码封装到run方法中。

 3,通过Thread类创建线程对象,并将Runnable接口的子类对象作为Thread类的构造函数的参数进行传递。

 为什么?因为线程的任务都封装在Runnable接口子类对象的run方法中。

 所以要在线程对象创建时就必须明确要运行的任务。

 4,调用线程对象的start方法开启线程。

 实现Runnable接口的好处:

 1,将线程的任务从线程的子类中分离出来,进行了单独的封装。

 按照面向对象的思想将任务的封装成对象。

 2,避免了java单继承的局限性。

 所以,创建线程的第二种方式较为常用。

 */

class Demo implements Runnable// extends Fu //准备扩展Demo类的功能,让其中的内容可以作为

// 线程的任务执行。

// 通过接口的形式完成。

{

public void run() {

show();

}

 

public void show() {

for (int x = 0; x < 20; x++) {

System.out.println(Thread.currentThread().getName() + "....." + x);

}

}

}

 

class ThreadDemo {

public static void main(String[] args) {

Demo d = new Demo();

Thread t1 = new Thread(d);

Thread t2 = new Thread(d);

t1.start();

t2.start();

// Demo d1 = new Demo();

// Demo d2 = new Demo();

// d1.start();

// d2.start();

}

}

 

 

多线程典型案例之卖票

/*

需求:卖票。

 */

/*

 线程安全问题产生的原因:

 1,多个线程在操作共享的数据。

 2,操作共享数据的线程代码有多条。

 当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算。

 就会导致线程安全问题的产生。

 解决思路;

 就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,

 其他线程时不可以参与运算的。

 必须要当前线程把这些代码都执行完毕后,其他线程才可以参与运算。 

 在java中,用同步代码块就可以解决这个问题。

 同步代码块的格式:

 synchronized(对象)

 {

 需要被同步的代码  ;

 }

 同步的好处:解决了线程的安全问题。

 同步的弊端:相对降低了效率,因为同步外的线程的都会判断同步锁。

 同步的前提:同步中必须有多个线程并使用同一个锁。

 */

class Ticket implements Runnable// extends Thread

{

private int num = 100;

Object obj = new Object();

 

public void run() {

while (true) {

synchronized (obj) {

if (num > 0) {

try {

Thread.sleep(10);

catch (InterruptedException e) {

}

System.out.println(Thread.currentThread().getName()

".....sale...." + num--);

}

}

}

}

}

 

class TicketDemo {

public static void main(String[] args) {

Ticket t = new Ticket();// 创建一个线程任务对象。

Thread t1 = new Thread(t);

Thread t2 = new Thread(t);

Thread t3 = new Thread(t);

Thread t4 = new Thread(t);

t1.start();

t2.start();

t3.start();

t4.start();

/*

 * Ticket t1 = new Ticket(); // Ticket t2 = new Ticket(); // Ticket t3 =

 * new Ticket(); // Ticket t4 = new Ticket(); t1.start(); 101

 * t1.start();//一个线程不能开启两次,会抛出无效线程状态异常 t1.start(); t1.start();

 */

}

}

 

线程中的join()方法

 

class Demo implements Runnable {

public void run() {

for (int x = 0; x < 50; x++) {

System.out.println(Thread.currentThread().toString() + "....." + x);

Thread.yield();

}

}

}

 

class JoinDemo {

public static void main(String[] argsthrows Exception {

Demo d = new Demo();

Thread t1 = new Thread(d);

Thread t2 = new Thread(d);

t1.start();

t2.start();

// t2.setPriority(Thread.MAX_PRIORITY);

// t1.join();//t1线程要申请加入进来,运行。临时加入一个线程运算时可以使用join方法。

for (int x = 0; x < 50; x++) {

// System.out.println(Thread.currentThread()+"....."+x);

}

}

}

 

线程之(多)生产者、(多)消费者模式

/*

生产者,消费者。 

多生产者,多消费者的问题。

if判断标记,只有一次,会导致不该运行的线程运行了。出现了数据错误的情况。

while判断标记,解决了线程获取执行权后,是否要运行!

notify:只能唤醒一个线程,如果本方唤醒了本方,没有意义。而且while判断标记+notify会导致死锁。

notifyAll解决了本方线程一定会唤醒对方线程的问题。

 */

class Resource {

private String name;

private int count = 1;

private boolean flag = false;

 

public synchronized void set(String name)//

{

while (flag)

try {

this.wait();

catch (InterruptedException e) {

}// t1 t0

this.name = name + count;// 烤鸭1 烤鸭2 烤鸭3

count++;// 2 3 4

System.out.println(Thread.currentThread().getName() + "... 生产者..."

this.name);// 生产烤鸭1 生产烤鸭2 生产烤鸭3

flag = true;

notifyAll();

}

 

public synchronized void out()// t3

{

while (!flag)

try {

this.wait();

catch (InterruptedException e) {

// t2 t3

System.out.println(Thread.currentThread().getName() + "... 消费者........"

this.name);// 消费烤鸭1

flag = false;

notifyAll();

}

}

 

class Producer implements Runnable {

private Resource r;

 

Producer(Resource r) {

this.r = r;

}

 

public void run() {

while (true) {

r.set("烤鸭");

}

}

}

 

class Consumer implements Runnable {

private Resource r;

 

Consumer(Resource r) {

this.r = r;

}

 

public void run() {

while (true) {

r.out();

}

}

}

 

class ProducerConsumerDemo {

public static void main(String[] args) {

Resource r = new Resource();

Producer pro = new Producer(r);

Consumer con = new Consumer(r);

Thread t0 = new Thread(pro);

Thread t1 = new Thread(pro);

Thread t2 = new Thread(con);

Thread t3 = new Thread(con);

t0.start();

t1.start();

t2.start();

t3.start();

}

}

 

注意if判断标记与notify()方法对应,while标记判断跟notifyAll()方法对应,这样才不会导致死

锁,否则任意一个搭配错的话都会导致死锁。

jdk1.5之后新的锁解决生产者和消费者问题

/* 

 104

 jdk1.5以后将同步和锁封装成了对象。 

 并将操作锁的隐式方式定义到了该对象中,

 将隐式动作变成了显示动作。

 Lock接口:  出现替代了同步代码块或者同步函数。将同步的隐式锁操作变成现实锁操作。

 同时更为灵活。可以一个锁上加上多组监视器。

 lock():获取锁。

 unlock():释放锁,通常需要定义finally代码块中。

 Condition接口:出现替代了Object中的wait notify notifyAll方法。

 将这些监视器方法单独进行了封装,变成Condition监视器对象。

 可以任意锁进行组合。

 await();

 signal();

 signalAll();

 */

import java.util.concurrent.locks.*;

 

class Resource {

private String name;

private int count = 1;

private boolean flag = false;

// 创建一个锁对象。

Lock lock = new ReentrantLock();

// 通过已有的锁获取该锁上的监视器对象。

// Condition con = lock.newCondition();

// 通过已有的锁获取两组监视器,一组监视生产者,一组监视消费者。

Condition producer_con = lock.newCondition();

Condition consumer_con = lock.newCondition();

 

public void set(String name)// t0 t1

{

lock.lock();

try {

while (flag)

// try{lock.wait();}catch(InterruptedException e){}// t1 t0

try {

producer_con.await();

catch (InterruptedException e) {

}// t1 t0

this.name = name + count;// 烤鸭1 烤鸭2 烤鸭3

count++;// 2 3 4

System.out.println(Thread.currentThread().getName()

"... 生 产 者5.0..." + this.name);// 生产烤鸭1 生产烤鸭2 生产烤鸭3

flag = true;

// notifyAll();

// con.signalAll();

consumer_con.signal();

finally {

lock.unlock();

}

}

 

public void out()// t2 t3

{

lock.lock();

try {

while (!flag)

// try{this.wait();}catch(InterruptedException e){} //t2 t3

try {

cousumer_con.await();

catch (InterruptedException e) {

// t2 t3

System.out.println(Thread.currentThread().getName()

"... 消费者.5.0......." + this.name);// 消费烤鸭1

flag = false;

// notifyAll();

// con.signalAll();

producer_con.signal();

finally {

lock.unlock();

}

}

}

 

class Producer implements Runnable {

private Resource r;

 

Producer(Resource r) {

this.r = r;

}

 

public void run() {

while (true) {

r.set("烤鸭");

}

}

}

 

class Consumer implements Runnable {

private Resource r;

 

Consumer(Resource r) {

this.r = r;

}

 

public void run() {

while (true) {

r.out();

}

}

}

 

class ProducerConsumerDemo2 {

public static void main(String[] args) {

Resource r = new Resource();

Producer pro = new Producer(r);

Consumer con = new Consumer(r);

Thread t0 = new Thread(pro);

Thread t1 = new Thread(pro);

Thread t2 = new Thread(con);

Thread t3 = new Thread(con);

t0.start();

t1.start();

t2.start();

t3.start();

}

}

 

线程间通讯

/*

 线程间通讯:

 多个线程在处理同一资源,但是任务却不同。

 */

//资源

class Resource {

String name;

String sex;

}

 

// 输入

class Input implements Runnable {

Resource r;

 

// Object obj = new Object();

Input(Resource r) {

this.r = r;

}

 

public void run() {

int x = 0;

while (true) {

synchronized (r) {

if (x == 0) {

r.name = "mike";

r.sex = "nan";

else {

r.name = "丽丽";

r.sex = "女女女女女女";

}

}

x = (x + 1) % 2;

}

}

}

 

// 输出

class Output implements Runnable {

Resource r;

 

// Object obj = new Object();

Output(Resource r) {

this.r = r;

}

 

public void run() {

while (true) {

synchronized (r) {

System.out.println(r.name + "....." + r.sex);

}

}

}

}

 

class ResourceDemo {

public static void main(String[] args) {

// 创建资源。

Resource r = new Resource();

// 创建任务。

Input in = new Input(r);

Output out = new Output(r);

// 创建线程,执行路径。

Thread t1 = new Thread(in);

Thread t2 = new Thread(out);

// 开启线程

t1.start();

t2.start();

}

}

 

线程中等待/唤醒机制

/*

 等待/唤醒机制。

 涉及的方法:

 1,wait():  让线程处于冻结状态,被wait的线程会被存储到线程池中。

 2,notify():唤醒线程池中一个线程(任意).

 3,notifyAll():唤醒线程池中的所有线程。

 这些方法都必须定义在同步中。

 因为这些方法是用于操作线程状态的方法。

 必须要明确到底操作的是哪个锁上的线程。

 109

 为什么操作线程的方法wait notify notifyAll定义在了Object类中? 

 因为这些方法是监视器的方法。监视器其实就是锁。

 锁可以是任意的对象,任意的对象调用的方式一定定义在Object类中。

 */

//资源

class Resource {

String name;

String sex;

boolean flag = false;

}

 

// 输入

class Input implements Runnable {

Resource r;

 

// Object obj = new Object();

Input(Resource r) {

this.r = r;

}

 

public void run() {

int x = 0;

while (true) {

synchronized (r) {

if (r.flag)

try {

r.wait();

catch (InterruptedException e) {

}

if (x == 0) {

r.name = "mike";

r.sex = "nan";

else {

r.name = "丽丽";

r.sex = "女女女女女女";

}

r.flag = true;

r.notify();

}

x = (x + 1) % 2;

}

}

}

 

// 输出

class Output implements Runnable {

Resource r;

 

// Object obj = new Object();

Output(Resource r) {

this.r = r;

}

 

public void run() {

while (true) {

synchronized (r) {

if (!r.flag)

try {

r.wait();

catch (InterruptedException e) {

}

System.out.println(r.name + "....." + r.sex);

r.flag = false;

r.notify();

}

}

}

}

 

class ResourceDemo2 {

public static void main(String[] args) {

// 创建资源。

Resource r = new Resource();

// 创建任务。

Input in = new Input(r);

Output out = new Output(r);

// 创建线程,执行路径。

Thread t1 = new Thread(in);

Thread t2 = new Thread(out);

// 开启线程

t1.start();

t2.start();

}

}

//以上代码也可以使用synchronized同步函数实现为:

class Resource {

private String name;

private String sex;

private boolean flag = false;

 

public synchronized void set(String name, String sex) {

if (flag)

try {

this.wait();

catch (InterruptedException e) {

}

this.name = name;

this.sex = sex;

flag = true;

this.notify();

}

 

public synchronized void out() {

if (!flag)

try {

this.wait();

catch (InterruptedException e) {

}

System.out.println(name + "...+...." + sex);

flag = false;

notify();

}

}

 

// 输入

class Input implements Runnable {

Resource r;

 

// Object obj = new Object();

Input(Resource r) {

this.r = r;

}

 

public void run() {

int x = 0;

while (true) {

if (x == 0) {

r.set("mike""nan");

else {

r.set("丽丽""女女女女女女");

}

x = (x + 1) % 2;

}

}

}

 

// 输出

class Output implements Runnable {

Resource r;

 

// Object obj = new Object();

Output(Resource r) {

this.r = r;

}

 

public void run() {

while (true) {

r.out();

}

}

}

 

class ResourceDemo3 {

public static void main(String[] args) {

// 创建资源。

Resource r = new Resource();

// 创建任务。

Input in = new Input(r);

Output out = new Output(r);

// 创建线程,执行路径。

Thread t1 = new Thread(in);

Thread t2 = new Thread(out);

// 开启线程

t1.start();

t2.start();

}

}

 

 

停止线程的方法

/*

 停止线程:

 1,stop方法。

 2,run方法结束。

 怎么控制线程的任务结束呢?

 任务中都会有循环结构,只要控制住循环就可以结束任务。

 控制循环通常就用定义标记来完成。

 但是如果线程处于了冻结状态,无法读取标记。如何结束呢?

 可以使用interrupt()方法将线程从冻结状态强制恢复到运行状态中来,让线程具备cpu的执行资格。

 当时强制动作会发生了InterruptedException,记得要处理

 */

class StopThread implements Runnable {

private boolean flag = true;

 

public synchronized void run() {

while (flag) {

try {

wait();// t0 t1

catch (InterruptedException e) {

System.out.println(Thread.currentThread().getName() + "....."

e);

flag = false;

}

System.out.println(Thread.currentThread().getName() + "......++++");

}

}

 

public void setFlag() {

flag = false;

}

}

 

class StopThreadDemo {

public static void main(String[] args) {

StopThread st = new StopThread();

Thread t1 = new Thread(st);

Thread t2 = new Thread(st);

t1.start();

t2.setDaemon(true);

t2.start();

int num = 1;

for (;;) {

if (++num == 50) {

// st.setFlag();

t1.interrupt();

// t2.interrupt();

break;

}

System.out.println("main...." + num);

}

System.out.println("over");

}

}

 

线程小练习(面试)

/*class Test implements Runnable

{

public void run(Thread t)

{}

}*/

//如果错误  错误发生在哪一行?错误在第一行,应该被abstract修饰

class ThreadTest {

public static void main(String[] args) {

new Thread(new Runnable() {

public void run() {

System.out.println("runnable run");

}

}) {

public void run() {

System.out.println("subThread run");

}

}.start();

new Thread() {

public void run() {

for (int x = 0; x < 50; x++) {

System.out.println(Thread.currentThread().getName()

"....x=" + x);

}

}

}.start();

for (int x = 0; x < 50; x++) {

System.out.println(Thread.currentThread().getName() + "....y=" + x);

}

Runnable r = new Runnable() {

public void run() {

for (int x = 0; x < 50; x++) {

System.out.println(Thread.currentThread().getName()

"....z=" + x);

}

}

};

new Thread(r).start();

}

}

 

 

waitsleep的区别

/*wait  和  sleep  区别?

 1,wait可以指定时间也可以不指定。

 sleep必须指定时间。 

 2,在同步中时,对cpu的执行权和锁的处理不同。

 wait:释放执行权,释放锁。

 sleep:释放执行权,不释放锁。*/

class Demo {

void show() throws InterruptedException {

synchronized (this)//

{

wait();// t0 t1 t2

}

}

 

void method() {

synchronized (this)// t4

{

// wait();

notifyAll();

}// t4

}

 

public static void main(String[] args) {

System.out.println("Hello World!");

}

}

 

多线程技术总结

多线程总结:

1,进程和线程的概念。

|--进程: 

|--线程:

 

2jvm中的多线程体现。

|--主线程,垃圾回收线程,自定义线程。以及他们运行的代码的位置。

3,什么时候使用多线程,多线程的好处是什么?创建线程的目的?

|--当需要多部分代码同时执行的时候,可以使用。

 

4,创建线程的两种方式。★★★★★

|--继承Thread

|--步骤

|--实现Runnable

|--步骤

|--两种方式的区别?

 

5,线程的5种状态。

对于执行资格和执行权在状态中的具体特点。

|--被创建:

|--运行:

|--冻结:

|--临时阻塞:

|--消亡:

 

6,线程的安全问题。★★★★★

|--安全问题的原因:

|--解决的思想:

|--解决的体现:synchronized

|--同步的前提:但是加上同步还出现安全问题,就需要用前提来思考。

|--同步的两种表现方法和区别:

|--同步的好处和弊端:

|--单例的懒汉式。

|--死锁。

 

7,线程间的通信。等待/唤醒机制。

|--概念:多个线程,不同任务,处理同一资源。

|--等待唤醒机制。使用了锁上的  wait notify notifyAll.  ★★★★★

|--生产者/消费者的问题。并多生产和多消费的问题。  while判断标记。用notifyAll唤醒对方。  ★★★★★

|--JDK1.5以后出现了更好的方案,★★★

Lock接口替代了synchronized 

Condition接口替代了Object中的监视方法,并将监视器方法封装成了Condition

和以前不同的是,以前一个锁上只能有一组监视器方法。现在,一个Lock锁上可以多组监视器方法对象。可以实现一组负责生产者,一组负责消费者。

|--waitsleep的区别。★★★★★

 

8,停止线程的方式。 

|--原理:

|--表现:--中断。

 

9,线程常见的一些方法。

|--setDaemon()

|--join();

|--优先级

|--yield();

|--在开发时,可以使用匿名内部类来完成局部的路径开辟。 

 

线程查漏综述

程序:源程序和字节码文件被称为"程序"Program),是一个静态的概念。

进程:执行中的程序叨做迚程(Process),是一个劢态的概念,迚程是程序的一次劢态执行过程,占用特定的地址空间,每个迚程由三部分组成即cpudatacode,每个迚程都是独立的,保有自己的cpu时间,代码和数据,即使同一份程序产生好几个线程,它们之间还是拥有自己的三样东西,缺点是内存的浪费和cpu的负担。

---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------                                             
0 0
原创粉丝点击