Java 线程宝典

此文 为垃圾文 本人复习用的 emmm

  • 多线程:指的是这个程序(一个进程)运行时产生了不止一个线程
  • 并行与并发:
    • 并行:多个cpu实例或者多台机器同时执行一段处理逻辑,是真正的同时。
    • 并发:通过cpu调度算法,让用户看上去同时执行,实际上从cpu操作层面不是真正的同时。并发往往在场景中有公用的资源,那么针对这个公用的资源往往产生瓶颈,我们会用TPS或者QPS来反应这个系统的处理能力。

  进程和线程的区分

  第一种实现方式:通过继承Thread类来实现的 线程

    摘要:

  

code:

package com.java.Thread;

public class MyThread {
    public static void main(String[] args){
        Apple a1 = new Apple("坏蛋");
            a1.start();
        Apple a2 = new Apple("好人");
            a2.start();
    }
}
class Apple extends Thread{
    private String name;

    public  Apple(String name){
        this.name = name;
    }

    public void run(){
        for (int i = 1; i < 10; i++){
            System.out.println(name+""+i);
        }
    }

}

每一个线程从的它的创建到销毁都有一个状态 如下是线程的各种状态:

线程的四种状态

然后实现现成的 第二种方式 实现 Runnable接口

  

code如下:

package cn.java.thread;

public class RunnableDemo {

    public static void main(String[] args) {
        Test t1 = new Test("haoren");
        Test t2 = new Test("hairen");
        Thread th1 = new Thread(t1);
        Thread th2 = new Thread(t2);
        th1.start();
        th2.start();
    }

}

class Test implements Runnable{
    private String name;

    public  Test(String name){
        this.name = name;
    }

    public void run(){
        for(int i=0;i<10;i++){
            System.out.println(name+":"+i);
        }
    }
}

  Thread和Runnable的关系

1.Thread是Ruuable的之类

     2.实际上Thread和Runable的关系 跟代理设计模式很像,  这里的Thread就是代理类。我们自己所实现的类才是real。

   Thread和Runnable的区别

     Runable可以共享数据

code如下:

package cn.java.thread;

public class ShareDemo {
    public static void main(String[] args) {
        Tickets t1 = new Tickets();

        Thread th1 = new Thread(t1);
        Thread th2 = new Thread(t1);
        th1.start();
        th2.start();

    }

}

class Tickets implements Runnable{
    private int ticket = 5;

    public void run(){
        for(int i=0;i<5;i++){
            if(ticket>0)
            System.out.print(ticket--);

        }
    }
}

然后 我说说这里面的 一个叫做jojn()的东东 网上各种帖子众说纷纭 而对他的理解就是 4个字  强制执行 做一个简单的验证吧.

package com.java.Thread;

public class MyJoin {
    public static void main(String[] ARGS){
        MyThread2 mt1 = new MyThread2();
        mt1.setName("线程1");
        mt1.start();
        for (int i = 0; i < 10; i++) {
            if(i==5){
                try {
                    mt1.join();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
            System.out.println(i);
        }

    }
}
class MyThread2 extends Thread {
    /*public MyThread(String string) {
    }*/

    public void run() {
        int i = 0;
        while (i < 10) {
            System.out.println(Thread.currentThread().getName());
            i++;
        }

    }
}

运行结果如下

然后在 说说 interrupt 中断  一个线程意味着在该线程完成任务之前停止其正在进行的一切,有效地中止其当前的操作。线程是死亡、还是等待新的任务或是继续运行至下一步,就取决于这个程序。虽然初次看来它可能显得简单,但是,你必须进行一些预警以实现期望的结果。你最好还是牢记以下的几点告诫。

首先,忘掉Thread.stop方法。虽然它确实停止了一个正在运行的线程,然而,这种方法是不安全也是不受提倡的,这意味着,在未来的Java版本中,它将不复存在。

一些轻率的家伙可能被另一种方法Thread.interrupt所迷惑。尽管,其名称似乎在暗示着什么,然而,这种方法并不会中断一个正在运行的线程(待会将进一步说明),正如Listing A中描述的那样。它创建了一个线程,并且试图使用Thread.interrupt方法停止该线程。Thread.sleep()方法的调用,为线程的初始化和中止提供了充裕的时间。线程本身并不参与任何有用的操作。

code如下:

package com.java.Thread;

public class MyInterrupt {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MyThread3 mt = new MyThread3();
        mt.start();

        try {
            Thread.sleep(2000);
            System.out.println("main休眠结束");
        } catch (InterruptedException e) {

            e.printStackTrace();
        }

        mt.interrupt();

    }
}

class MyThread3 extends Thread{
    public void run(){
        System.out.println("进入run");
        try {
            Thread.sleep(8000);

        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            //e.printStackTrace();
            System.out.println("run休眠结束!!!");//sleep被中断会抛出InterruptedException 推荐直接抛出 不要捕获
        }
        System.out.println("run运行结束");
    }

}

然后来到线程礼让  俗话点说 就是 线程A是个君子 看见线程B是个 美女就干什么都让着她 让她先过..

code如下:

package com.java.Thread;
//线程礼让
public class MyYield {
    public static void main(String[] ARGS){
        MyThred m1 = new MyThred();
            Thread t1 = new Thread(m1,"李四");
            Thread t2 = new Thread(m1,"王五");
            t1.start();
            t2.start();
    }
}
class MyThred implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 5; i++){
            System.out.println(Thread.currentThread().getName()+"运行>>>>>" + i);
            if (i==2) {
                System.out.println("线程礼让");
                Thread.currentThread().yield();
            }
        }
    }
}

然后 来到  setdaenmo 后台线程设置

Java中线程分为两种类型:用户线程守护线程。通过Thread.setDaemon(false)设置为用户线程;通过Thread.setDaemon(true)设置为守护线程。如果不设置次属性,默认为用户线程。

用户线程和守护线程的区别:

1. 主线程结束后用户线程还会继续运行,JVM存活;主线程结束后守护线程和JVM的状态又下面第2条确定。

2.如果没有用户线程,都是守护线程,那么JVM结束(随之而来的是所有的一切烟消云散,包括所有的守护线程)。

code如下:

package com.java.Thread;

public class SetDaemon {
    public static void main(String[] ARGS){
        Persons p1 = new Persons();
            Thread th = new Thread(p1);
                th.setDaemon(true);//如果不加此语句就永远无法结束
        th.start();

    }
}
class Persons implements Runnable{

    @Override
    public void run() {
        while (true){
            System.out.println("哈哈哈哈哈哈sss");
        }
    }
}

然后 设置线程的优先级别 这点要说说 高的不一定会优先执行.

这是定义表

通过 setPriority方法来执行

来到重点中的重点  拿个小本本记住 线程安全

  导致线程安全出现的原因:

所以 我们为了解决这个问题 推出了 同步 synchronized

  

然后同步又有两种模式 一种是同步代码块 另外一种是同步函数 这两种同步加锁的方式不一样 = =且看我细细道来

  先看看code

package cn.tread;

public class TicketDemo {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Person2 p1 = new Person2("haoren");
        Thread t1 = new Thread(p1);
        Thread t2 = new Thread(p1);
        t1.start();
        t2.start();

    }

}

class Person2 implements Runnable {
    private String name;
    private int tickets = 5;

    public Person2(String name) {
        this.name = name;
    }
   //同步代码块 需要的锁是 任意对象~
    Object object1 = new Object();

    public void run() {

        for (int i = 0; i < 5; i++) {
            synchronized (object1) {//object1就是传说中的锁,要同步必须使用同一个锁
                if (tickets > 0) {
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {

                        e.printStackTrace();
                    }

                    System.out.println(tickets--);
                }
            }
        }

    }
}

观察上面的代码  我们 有了一个总结 同步代码的锁可以是任意对象

然后是同步的前提

同步的弊端

然后我们说说同步函数

package cn.java.thread;

/*
 证明同步函数用的是this这把锁
 */
public class Tickets1 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        /*
         * GetTickets gt1 = new GetTickets(); GetTickets gt2 = new GetTickets();
         * GetTickets gt3 = new GetTickets(); gt1.setName("窗口一");
         * gt2.setName("窗口二"); gt3.setName("窗口三"); gt1.start(); gt2.start();
         * gt3.start();
         */
        GetTickets2 gt = new GetTickets2();
        Thread th1 = new Thread(gt, "窗口一");
        Thread th2 = new Thread(gt, "窗口二");
        Thread th3 = new Thread(gt, "窗口三");
        th1.start();
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        gt.flag = true;
        th2.start();
        th3.start();
    }

}

class GetTickets2 implements Runnable {

    private int tickets = 10;
    boolean flag = false;
    Object ob = new Object();
    public void run() {
        if (flag) {
            for (int i = 0; i < 10; i++) {
                //synchronized (ob) {//如果用ob就无法同步
                synchronized (this) {
                    if (tickets > 0) {
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName()
                                + "卖出" + (tickets--) + "号票"+":同步代码块");
                    }
                }

            }

        } else {
            for (int i = 0; i < 10; i++) {
                function();

            }

        }
    }

    public synchronized void function() {

        if (tickets > 0) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "卖出"
                    + (tickets--) + "号票"+":同步函数");

        }
    }

}
/*
 * class GetTickets extends Thread{ //private static int tickets = 10; private
 * int tickets = 10; public void run(){
 *
 * for (int i = 0; i < 10; i++) { if(tickets>0){
 * System.out.println(Thread.currentThread().getName()+"卖出"+(tickets--)+"号票"); }
 * } } }
 */

通过 观察我们不难发现

余下的我在下一个分P写...

时间: 2024-10-19 09:13:29

Java 线程宝典的相关文章

Java面试宝典

http://www.cnblogs.com/bluestorm/p/6429894.html Java面试宝典 面向对象的三个特征 封装,继承,多态.这个应该是人人皆知.有时候也会加上抽象. 多态的好处 允许不同类对象对同一消息做出响应,即同一消息可以根据发送对象的不同而采用多种不同的行为方式(发送消息就是函数调用).主要有以下优点: 可替换性:多态对已存在代码具有可替换性. 可扩充性:增加新的子类不影响已经存在的类结构. 接口性:多态是超累通过方法签名,想子类提供一个公共接口,由子类来完善或

Java面试宝典-2017

Java面试宝典2017版 一. Java基础部分...................................................................................................... 7 1.一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?..... 7 2.Java有没有goto?.......................................................

java面试宝典(蓝桥学院)

Java面试宝典(蓝桥学院) 回答技巧 这套面试题主要目的是帮助那些还没有java软件开发实际工作经验,而正在努力寻找java软件开发工作的学生在笔试/面试时更好地赢得好的结果.由于这套试题涉及的范围很泛,很广,很杂,大家不可能一天两天就看完和学完这套面试宝典,即使你已经学过了有关的技术,那么至少也需要半个月的时间才能消化和掌握这套面试宝典,所以,大家应该早作准备,从拿到这套面试宝典之日起,就要坚持在每天闲暇之余学习其中几道题目,日积月累,等到出去面试时,一切都水到渠成,面试时就自然会游刃有余了

java 线程详解

5月7号  周末看了一下线程方面的内容 ,边看视频边看书还附带着参考了很多人的博客,一天的收获,写下来整理一下:感觉收获还是挺多的:过段时间可能看完java  这几大块要去看一下关于spring boot  的内容顺便  也整理一下:附上我参考的 几本书: 关于java  线程,首先要了解一下线程和进程之间的关系.区别以及他们之间的概念: 首先是线程: 什么是线程? 线程是在程序执行过程中能够执行部分代码的一个执行单元,也看看做是一个轻量级的进程:线程是程序内的程序控制流只能使用程序内分配给程序

Java线程工作内存与主内存变量交换过程及volatile关键字理解

Java线程工作内存与主内存变量交换过程及volatile关键字理解 1. Java内存模型规定在多线程情况下,线程操作主内存变量,需要通过线程独有的工作内存拷贝主内存变量副本来进行.此处的所谓内存模型要区别于通常所说的虚拟机堆模型: 2. 线程独有的工作内存和进程内存(主内存)之间通过8中原子操作来实现,如下图所示: 原子操作的规则(部分): 1) read,load必须连续执行,但是不保证原子性. 2) store,write必须连续执行,但是不保证原子性. 3) 不能丢失变量最后一次ass

java线程

Java线程详解 1.操作系统中的线程和进程讲解: 现在的操作系统大都是多任务操作系统,多线程是多任务的一种. 进程是指操作系统中运行的一个程序,每个进程都有自己的一块内存空间,一个进程中可以启动多个线程. 线程是指进程中的一个执行流程,一个进程中可以运行多个线程.比如java.exe进程中可以运行很多线程.线程总是属于某个进程,进程中的多个线程共享进程的内存. “同时”执行是人的感觉,在线程之间实际上轮换执行. Java线程的两种具体实现方法: 第一种继承:具体代码实现如下: Public (

Java 线程第三版 第四章 Thread Notification 读书笔记

一.等待与通知 public final void wait() throws InterruptedException 等待条件的发生. public final void wait(long timeout) throws InterruptedException 等待条件的发生.如果通知没有在timeout指定的时间内发生,它还是会返回. public final void wait(long timeout, int nanos) throws InterruptedException

Java线程使用大全

1.线程实现 1.Thread类 构造方法: 案例代码: public class Ex10_1_CaseThread extends Thread {// 创建一个类继承(extend)Thread类 String studentName; public Ex10_1_CaseThread(String studentName) {// 定义类的构造函数,传递参数 System.out.println(studentName + "申请访问服务器"); this.studentNam

java线程五种状态

java线程五种状态: 创建 -> 就绪 -> 运行 -> 销毁 创建 -> 就绪 -> 运行 -> 等待(缺少资源) -> 销毁 下图:各种状态转换