java基础--多线程

进程:针对操作系统,一个系统多个任务进程。比如开一个视频播放,开一个QQ

线程:是进程中的运行单元。

多线程:一个项目或应用可以分多个线程并行执行,由CPU分配时间片进行调用。

线程的状态

 

 

 

 

1.新建状态    new Thread()

2.就绪状态    start()

3.运行状态    run

4.阻塞状态    失去CPU的时间片

5.线程终止    线程中的方法执行完毕

创建线程的方式

1.继承Thread 重写run方法,缺点单继承,不能再继承其他类

2.实现Runnable接口(静态代理  Thread代理角色)好处:可以继承或实现其他接口

3.实现Callable接口    优点:可以返回值,可以抛出自定义异常

 

 

 

 

 

合并线程,插队

join()

 

/**
 * 线程阻塞
 * @author Administrator
 *
 */
public class ZuseThread extends Thread{

    public void run() {
        
        for (int i = 0; i < 500; i++) {
            System.out.println("ZuseThread-->"+i);
        }
        
        
    }
    
    public static void main(String[] args) throws InterruptedException {
        
        ZuseThread zuseThread = new ZuseThread();
        zuseThread.start();
        
        for (int i = 0; i < 500; i++) {
            
            if(i==50){
                //当mian线程执行到i=50的时候mian线程阻塞开始执行ZuseThread线程,执行完后再执行mian线程
//Thread.yield();静态方法,暂停当前线程mian,让出时间片
zuseThread.join(); } System.out.println("main-->"+i); } } }

 

 

 

暂停线程

yield()   静态方法,暂停下一,不是绝对的,接下是还否暂停取决于CPU

sleep()    静态方法,不释放锁,一般用于模拟延迟,倒计时

多线程并发执行,JAVA能保证每个线程都执行,不能保证执行顺序

线程优先级:1-10   优先级越高获得CPU的时间片的机会越多,不是绝对的

setPriority(1)

 

并发

多个线程访问一个资源,要确保资源的安全,需要加同步

1.同步块   synchronized (对象引用){\

}

2.同步方法  public synchronized void  aaa(){}

 

 

public class TT implements Runnable {

    public Integer b = 1000;

    public  void m1() throws InterruptedException {
        synchronized(this.b){
            this.b = 20000;
            Thread.sleep(5000);
            System.out.println(b);
        }
    }

    public synchronized void m3() throws InterruptedException {
        this.b = 20000;
        Thread.sleep(5000);
        System.out.println(b);
    }


    public  void m2(){
        System.out.println(b);

    }

    @Override
    public void run() {
        try {
            m1();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    public static void main(String []args) throws InterruptedException {
        TT tt = new TT();
        Thread t1 = new Thread(tt);
        t1.start();
        System.out.println("开始");
        Thread.sleep(1000);
        tt.m2();
    }
}

 

 

 

 

 线程不安全

public class Qiangpiao implements Runnable{
    private int num = 50;
    @Override
    public void run() {
        while(true){
            
            if(num<=0){
                break;
            }
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
            System.out.println(Thread.currentThread().getName()+"抢票"+num);
            num--;
        }
        
    }
    
    public static void main(String[] args) {
        Qiangpiao qiangpiao = new Qiangpiao();
        Thread t1 = new Thread(qiangpiao, "甲");
        Thread t2 = new Thread(qiangpiao, "乙");
        Thread t3 = new Thread(qiangpiao, "丙");
        t1.start();
        t2.start();
        t3.start();
        
    }
    

}

同步关键字

public class Qiangpiao implements Runnable{
    private int num = 50;
    
    private boolean flag = true;
    
    
    public synchronized void  tongbu(){
        
        if(num<=0){
            flag = false;
            return;
        }
        /*try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }*/
        
        System.out.println(Thread.currentThread().getName()+"抢票"+num);
        num--;
        
        
    }
    
    
    
    @Override
    public void run() {
        while(flag){
            tongbu();
            
        }
        
    }
    
    public static void main(String[] args) {
        Qiangpiao qiangpiao = new Qiangpiao();
        Thread t1 = new Thread(qiangpiao, "甲");
        Thread t2 = new Thread(qiangpiao, "乙");
        Thread t3 = new Thread(qiangpiao, "丙");
        t1.start();
        t2.start();
        t3.start();
        
    }
    

}

死锁

/**
 * 线程死锁,有同步才会有死锁
 * @author Administrator
 *
 */
public class Sisuo {

    
    public static void main(String[] args) {
        Object money = new Object();
        Object goods = new Object();
        
        Thread1 thread1 = new Thread1(money, goods);
        Thread t1 = new Thread(thread1);
        Thread2 thread2 = new Thread2(money, goods);
        Thread t2 = new Thread(thread2);
        t1.start();
        t2.start();
        
    }
    
}


class Thread1 implements Runnable{
    
    Object money;
    
    Object goods;
    
    
    public Thread1(Object money, Object goods) {
        super();
        this.money = money;
        this.goods = goods;
    }

    @Override
    public void run() {
        while(true){
            synchronized (money) {
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (goods) {
                    
                }
            }
            System.out.println("一手给钱");
        }
    }
}


class Thread2 implements Runnable{
    
    Object money;
    
    Object goods;
    
    
    public Thread2(Object money, Object goods) {
        super();
        this.money = money;
        this.goods = goods;
    }

    @Override
    public void run() {
        while(true){
            synchronized (goods) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (money) {
                    
                }
            }
            System.out.println("一手给货");
        }
    }
    
    
}

解决并发可能出现的死锁:生产者消费者模式

/**
 * 生产者消费者
 * @author Administrator
 *
 */
public class TestShengchanzhe {

    public static void main(String[] args) {
        
        Movie m = new Movie();

        Player player = new Player(m);
        
        Watch watch = new Watch(m);
        
        new Thread(player).start();
        new Thread(watch).start();
        
        
        
    }

}

class Movie{
    
    private String pic;
    //true 生产者生产,消费者等待,生产完成后通知消费
    //false 消费者消费,生产者等待,消费完成后通知生产
    private boolean flag = true;
    
    public synchronized void play(String pic) throws InterruptedException{
        
        if(!flag){
            this.wait();//会释放锁
        }
        
        Thread.sleep(500);
        this.pic = pic;
        this.notify();//通知消费
        this.flag = false;
        System.out.println("生产者生产-->"+pic);
    }
    
    public synchronized void watch() throws InterruptedException{
        if(flag){
            this.wait();
        }
        
        Thread.sleep(200);
        this.notify();
        this.flag = true;
        System.out.println("消费者消费-->"+pic);
        
    }
    
}

class Player implements Runnable{
    
    Movie m;
    
    public Player(Movie m) {
        super();
        this.m = m;
    }


    @Override
    public void run() {
        while(true){
            try {
                m.play("馒头");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
}

class Watch implements Runnable{
    
    Movie m;
    
    public Watch(Movie m) {
        super();
        this.m = m;
    }

    @Override
    public void run() {
        while(true){
            try {
                m.watch();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
    }
    
}

 当一个进程有 500 个线程在跑的话,那性能已经是很低很低了。Tomcat 默认配置的最大请求数是 150,也就是说同时支持 150 个并发,当然了,也可以将其改大。
当某个应用拥有 250 个以上并发的时候,应考虑应用服务器的集群。
具体能承载多少并发,需要看硬件的配置,CPU 越多性能越高,分配给 JVM 的内存越多性能也就越高,但也会加重 GC 的负担。
操作系统对于进程中的线程数有一定的限制:
Windows 每个进程中的线程数不允许超过 2000
Linux 每个进程中的线程数不允许超过 1000
另外,在 Java 中每开启一个线程需要耗用 1MB 的 JVM 内存空间用于作为线程栈之用。
Tomcat的最大并发数是可以配置的,实际运用中,最大并发数与硬件性能和CPU数量都有很大关系的。更好的硬件,更多的处理器都会使Tomcat支持更多的并发。
Tomcat 默认的 HTTP 实现是采用阻塞式的 Socket 通信,每个请求都需要创建一个线程处理。这种模式下的并发量受到线程数的限制,但对于 Tomcat 来说几乎没有 BUG 存在了。
Tomcat 还可以配置 NIO 方式的 Socket 通信,在性能上高于阻塞式的,每个请求也不需要创建一个线程进行处理,并发能力比前者高。但没有阻塞式的成熟。
这个并发能力还与应用的逻辑密切相关,如果逻辑很复杂需要大量的计算,那并发能力势必会下降。如果每个请求都含有很多的数据库操作,那么对于数据库的性能也是非常高的。
对于单台数据库服务器来说,允许客户端的连接数量是有限制的。
并发能力问题涉及整个系统架构和业务逻辑。
系统环境不同,Tomcat版本不同、JDK版本不同、以及修改的设定参数不同。并发量的差异还是满大的。
maxThreads="1000" 最大并发数
minSpareThreads="100"///初始化时创建的线程数
maxSpareThreads="500"///一旦创建的线程超过这个值,Tomcat就会关闭不再需要的socket线程。
acceptCount="700"// 指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理

posted @ 2016-11-26 20:08  jentary  阅读(360)  评论(0编辑  收藏  举报