Java多线程总结(一)

1.多线程的优势:同时运行多部分代码;劣势:效率降低。JVM在启动的时候,至少启动了两个线程,执行main函数的线程,垃圾回收线程。
2.垃圾回收机制,System.gc()方法告诉JVM调用finalize方法,但不一定立即执行。
3.创建线程的方式:第一种:继承Thread类。示例如下:

package heima.person.caizhanqi.basetest;

public class ThreadDemo extends Thread {
    @Override
    public void run() {
        // TODO Auto-generated method stub
        super.run();
        for (int i = 0; i < 10; i++) {
            System.out.println(
            Thread.currentThread().getName()
            +"-----------"+this.getId());
        }
    }
    public static void main(String[] args) {

        new ThreadDemo().start();
        for (int i = 0; i < 10; i++) {
            +"-----------"
            +Thread.currentThread().getId());
        }
        new ThreadDemo().start();
        new ThreadDemo().start();
    }
}

.
4.第二种:实现Runnable接口:优点:将线程的任务从线程的子类中分离出来,进行了单独的封装,按照面向对象的思想将任务封装成对象。示例如下:

public class ThreadDemo implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println(Thread.currentThread().getName() 
            + "--------"+ i + "--------" 
            + Thread.currentThread().getId());
        }
    }

    public static void main(String[] args) {
        ThreadDemo demo = new ThreadDemo();
        new Thread(demo).start();
        new Thread(demo).start();
        new Thread(demo).start();
    }

}

.
5.Thread类,Runnable接口模拟实现,如下:

public class ThreadDemo{
    private Runnable r;
    public ThreadDemo(){

    }
    public ThreadDemo(Runnable r){
        this.r = r;
    }

    public void run(){
        if(r!=null)
            r.run();
    }

    public void start(){
        run();
    }

}

.
6.线程安全问题示例:

public class ThreadSecurity implements Runnable {
    private int num;

    public ThreadSecurity() {
        // TODO Auto-generated constructor stub
    }

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

    @Override
    public void run() {
        while (num > 0) {
            try {
                System.out.println(
                    Thread.currentThread().getName() 
                    + "----sale..."+ num);
                num--;
                Thread.sleep(100);
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
    }

    public static void main(String[] args) {
        ThreadSecurity t = new ThreadSecurity(10);
        new Thread(t).start();
        new Thread(t).start();
        new Thread(t).start();
    }
}

.
7.线程安全问题产生的原因:1.多个线程在操作共享的数据;2.操作共享数据的线程代码有多条。由此可知,当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算,就会导致线程安全问题的产生。
8.解决线程安全问题的方案:将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,其他线程不能参与运算。必须要当前线程把这些代码都执行完毕,其他线程才能参与运算。
9.同步代码块:修饰词:synchronized.同步的好处:解决了线程的安全问题;弊端:当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中降低程序运行的效率。同步的前提:必须有多个线程使用同一个锁。
10.Synchroized修饰的函数锁是this,修饰的静态变量,锁是类的字节码文件,修饰的成员变量,锁可以是任意对象。
11.同步示例:

public class ThreadSynchronized implements Runnable {
    private int num;
    private boolean flag;
    public ThreadSynchronized() {
        flag = true;
        num = 100;
    }

    @Override
    public void run() {
        if (flag) {
            while (true) {
                synchronized (this) {
                    if (num > 0) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(
                            Thread.currentThread().getName()
                                + "--true--" + num--);
                    }
                }
            }
        } else {
            while (true)
                show();
        }
    }
    public synchronized void show() {
        if (num > 0) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(
                Thread.currentThread().getName() + "--flase--"
                    + num--);
        }
    }
    public static void main(String[] args) {
        ThreadSynchronized ts = new ThreadSynchronized();
        new Thread(ts).start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        ts.flag = false;
        new Thread(ts).start();
        new Thread(ts).start();
    }
}

.
12.多线程下的单例设计模式:1.饿汉式:不存在多个线程共同操作数据的情况,线程安全。

class SingleThread{
    private static final SingleThread s = new SingleThread(); 
    private SingleThread(){} 
    public SingleThread getSingleThread(){
        return s;
    }
}

2.懒汉式:存在线程安全问题。

Class SingleThread{
    private static final SingleThread s = null;
    Private SingleThread(){}
    public SingleThread getSingleThread(){
        if(s == null){
            sysnchronized(SingleThread.class){
                if(s == null){
                S = new SingleThread();
                }
            }
        }
        return s;
    }
}

.
13.死锁:想要获取的锁被别的线程所占有,互相不释放,导致程序不能继续执行下去。死锁示例:

public class DeadLock implements Runnable {
    private int num = 1000;
    private boolean flag;
    private Object obj = new Object();
    @Override
    public void run() {
        if (flag) {
            while (true) {
                synchronized (obj) {
                    if (num > 0) {
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(
                            Thread.currentThread().getName()
                                + "--true--" + num--);
                    }
                    show();
                }
            }
        } else {
            while (true) {
                show();
            }
        }
    }
    public synchronized void show() {
        synchronized (obj) {
            if (num > 0) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()
                        + "--false--" + num--);
            }
        }
    }
    public static void main(String[] args) {
        DeadLock dl = new DeadLock();
        dl.flag = true;
        new Thread(dl).start();
        new Thread(dl).start();
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        dl.flag = false;
        new Thread(dl).start();
    }
}

.
14.多线程间的通信:多个线程在处理统一资源,但是任务不同,这时就需要多线程间的通信。等待/唤醒机制涉及的方法:1.wait(),让线程处于冻结状态,被wait()的线程会放在线程池中;2.notify(),唤醒线程池中的一个线程;3.notifyAll(),唤醒线程池中的所有线程。PS:wait释放执行权,释放锁。以上三个方法都定义在同步中,因为这些方法是用于操作线程状态的方法。
15.一对一的线程通信,线程被唤醒之后,会继续从之前wait的部分之后开始执行任务。一对一线程通信如下:

class Resource{
    private int num = 0;
    private boolean flag;
    public void setResource(){
        synchronized(this){
            System.out.println("set...wait");
            if(flag)
                try {
                    Thread.sleep(100);
                    wait();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            System.out.println("set....notify");
            num++;
            flag = true;
            System.out.println("in...."+num);
            notify();
        }
    }
    public void outResource(){
        synchronized(this){
            System.out.println("out...wait");
            if (!flag)
                try {
                    Thread.sleep(100);
                    wait();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            System.out.println("out...notify");
            System.out.println("out...."+num);
            flag = false;
            notify();
        }
    }
}
class InDemo implements Runnable{
    private Resource r;
    public InDemo(Resource r) {
        this.r = r;
    }
    @Override
    public void run() {
        while(true){
            r.setResource();
        }
    }
}
class OutDemo implements Runnable{
    private Resource r;
    public OutDemo(Resource r) {
        this.r = r;
    }
    @Override
    public void run() {
        while(true)
            r.outResource();
    }
}
public class ThreadDemo{
    public static void main(String[] args) {
        Resource r = new Resource();
        InDemo in = new InDemo(r);
        OutDemo out = new OutDemo(r);
        new Thread(in).start();
        new Thread(out).start();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值