java学习笔记(20-多线程)

1. Thread类

1.1 继承实现

package com.daigua20;

public class ThreadDemo {
    public static void main(String[] args) {
        MyThread t1 = new MyThread();
        // 修改线程名字
        t1.setName("呆瓜");
        // 启动任务
        t1.start();

        MyThread t2 = new MyThread();
        // 修改线程名字
        t2.setName("猪娃");
        // 启动任务
        t2.start();

    }
}

class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(getName() + ":" + i);
        }
    }
}

1.2 Runnable接口实现

package com.daigua20;

public class ThreadDemo2 {
    public static void main(String[] args) {
        // 实例出Runnable接口子类的对象
        MyThread2 r1 = new MyThread2(10);
        MyThread2 r2 = new MyThread2(10);

        // 用Runnable子类构造Thread类的实例
        Thread t1 = new Thread(r1);
        Thread t2 = new Thread(r2);

        // start方法启动任务
        t1.start();
        t2.start();
    }
}

// 定义Runnable接口的子类,重写run方法
class MyThread2 implements Runnable {
    int num;

    public MyThread2(int num) {
        this.num = num;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + ":" + i + num);
        }
    }
}

2.线程安全

2.1 资源共享导致的问题

package com.daigua20;


public class ThreadDemo3 {
    public static void main(String[] args) {
        TicketThread r1 = new TicketThread();

        Thread t1 = new Thread(r1);
        Thread t2 = new Thread(r1);
        Thread t3 = new Thread(r1);

        t1.start();
        t2.start();
        t3.start();
    }
}


class TicketThread implements Runnable {
    // 车票数量一百张
    int tickets = 100;

    @Override
    public void run() {
        while (true) {
            if (tickets > 0) {
                try {
                    Thread.sleep(100);
                    tickets -= 1;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ":" + tickets);
            }
        }
    }
}

2.2解决方法

2.2.1 使用同步代码块

格式:
  synchronized(锁对象){
      //需要同步的代码
}
package com.daigua20;
/*
 *  synchronized:同步(锁),可以修饰代码块和方法,被修饰的代码块和方法一旦被某个线程访问,则直接锁住,其他的线程将无法访问
 *
 * 同步代码块:
 *          synchronized(锁对象){
 *
 *          }
 *
 * 注意:锁对象需要被所有的线程所共享
 *
 *
 * 同步:安全性高,效率低
 * 非同步:效率高,但是安全性低
 *
 */

public class ThreadDemo4 {
    public static void main(String[] args) {
        TicketThread2 r1 = new TicketThread2();
        
        Thread t1 = new Thread(r1);
        Thread t2 = new Thread(r1);
        Thread t3 = new Thread(r1);
        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t1.start();
        t2.start();
        t3.start();
    }
}


class TicketThread2 implements Runnable {
    // 车票数量一百张
    int tickets = 100;
    Object obj = new Object();

    @Override
    public void run() {
        while (true) {
            synchronized (obj) {
                if (tickets > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + ":" + tickets--);
                }
            }
        }
    }
}

2.2.2 使用同步方法

 格式:
  修饰符 synchronized 返回值 方法名(){

}
package com.daigua20;
/*
 * 同步方法:使用关键字synchronized修饰的方法,一旦被一个线程访问,则整个方法全部锁住,其他线程则无法访问
 *
 * synchronized
 * 注意:
 *      非静态同步方法的锁对象是this
 *      静态的同步方法的锁对象是当前类的字节码对象
 */
public class ThreadDemo5 {
    public static void main(String[] args) {
        TicketThread3 tt = new TicketThread3();

        Thread t1 = new Thread(tt);
        Thread t2 = new Thread(tt);
        Thread t3 = new Thread(tt);

        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        t3.start();
        t2.start();
        t1.start();
    }
}


class TicketThread3 implements Runnable {
    // 车票数量一百张
    static int  tickets = 100;
//    Object obj = new Object();

    @Override
    public void run() {
        while (true) {
                if (tickets > 0) {
//                    method();
                    method2();
            }
        }
    }

    private synchronized void method(){
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + ":" + tickets--);
    }

    private static synchronized void method2(){
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + ":" + tickets--);
    }

}

猜你喜欢

转载自www.cnblogs.com/daigua/p/java-xue-xi-bi-ji-20duo-xian-cheng.html