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写...
Java 线程宝典的更多相关文章
- java面试宝典(蓝桥学院)
Java面试宝典(蓝桥学院) 回答技巧 这套面试题主要目的是帮助那些还没有java软件开发实际工作经验,而正在努力寻找java软件开发工作的学生在笔试/面试时更好地赢得好的结果.由于这套试题涉及的范围 ...
- Java 面试宝典-2017
http://www.cnblogs.com/nelson-hu/p/7190163.html Java面试宝典-2017 Java面试宝典2017版 一. Java基础部分........... ...
- Java面试宝典-2017
Java面试宝典2017版 一. Java基础部分........................................................................... ...
- Java面试宝典2018
转 Java面试宝典2018 一. Java基础部分…………………………………………………………………………………….. 7 1.一个“.java”源文件中是否可以包括多个类(不是内部类)?有什么限制 ...
- Java面试宝典(2018版)
置顶 2018年11月10日 23:49:18 我要取一个响亮的昵称 阅读数:8893 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/chen ...
- java面试宝典2019(好东西先留着)
java面试宝典2019 1.meta标签的作用是什么 2.ReenTrantLock可重入锁(和synchronized的区别)总结 3.Spring中的自动装配有哪些限制? 4.什么是可变参数? ...
- Java面试宝典(1)Java基础部分
Java面试宝典 题目,日积月累,等到出去面试时,一切都水到渠成,面试时就自然会游刃有余了. 答题时,先答是什么,再答有什么作用和要注意什么(这部分最重要,展现自己的心得) 答案的段落分别,层次分明, ...
- Java 线程池中的线程复用是如何实现的?
前几天,技术群里有个群友问了一个关于线程池的问题,内容如图所示: 关于线程池相关知识可以先看下这篇:为什么阿里巴巴Java开发手册中强制要求线程池不允许使用Executors创建? 那么就来和大家探讨 ...
- 新鲜出炉!JAVA线程池精华篇深度讲解,看完你还怕面试被问到吗?
前言 前两天趁着假期在整理粉丝私信的时候看到一个粉丝朋友的私信跟我说自己现在正在复习准备面试,自己在复习到线程池这一块的时候有点卡壳,总感觉自己差了点什么.想要我帮他指导一下.这不趁着假期我也有时间我 ...
随机推荐
- Ion-affix & Ion-stick 仿IOS悬浮列表插件
Ion-affix & Ion-stick 仿IOS悬浮列表插件 Ion-affix 1.相关网页 Ion-affix 2.环境准备: 执行命令 bower install ion-affix ...
- WPF:动态显示或隐藏Listview的某一列
这几天做项目,需要做个listview满足能够动态显示或隐藏某些列,由于自己是菜鸟水平,查了两天资料也没有想出解决办法.就在我山穷水尽的时候看到了Mgen的一篇博客,给了我很大启发,所以我也决定把自己 ...
- 消息队列NetMQ 原理分析4-Socket、Session、Option和Pipe
消息队列NetMQ 原理分析4-Socket.Session.Option和Pipe 前言 介绍 目的 Socket 接口实现 内部结构 Session Option Pipe YPipe Msg Y ...
- Ajax获取数据的几种格式和解析方式
一.什么是ajax AJAX的全称是Asynchronous JavaScript and XML(是异步的 javascript 和 XML). ajax不是新的编程语言,而是一种使用现有标准的 ...
- php 时间问题
获得简单的日期 date() 函数的格式参数是必需的,它们规定如何格式化日期或时间. 下面列出了一些常用于日期的字符: d - 表示月里的某天(01-31) m - 表示月(01-12) Y - 表示 ...
- Java IO设计模式(装饰模式与适配器模式)
01. 装饰模式 1. 定义 Decorator装饰器,就是动态地给一个对象添加一些额外的职责,动态扩展,和下面继承(静态扩展)的比较.因此,装饰器模式具有如下的特征: 它必须持有一个被装饰的对象(作 ...
- mongoDB 学习笔记纯干货(mongoose、增删改查、聚合、索引、连接、备份与恢复、监控等等)
最后更新时间:2017-07-13 11:10:49 原始文章链接:http://www.lovebxm.com/2017/07/13/mongodb_primer/ MongoDB - 简介 官网: ...
- python机器学习实战(二)
python机器学习实战(二) 版权声明:本文为博主原创文章,转载请指明转载地址 http://www.cnblogs.com/fydeblog/p/7159775.html 前言 这篇noteboo ...
- POJ 2296 Map Labeler / ZOJ 2493 Map Labeler / HIT 2369 Map Labeler / UVAlive 2973 Map Labeler(2-sat 二分)
POJ 2296 Map Labeler / ZOJ 2493 Map Labeler / HIT 2369 Map Labeler / UVAlive 2973 Map Labeler(2-sat ...
- Android - 读取文件存储的数据
存取手机中的文件数据. 写入和读取的操作格式均为UTF-8. import java.io.File; import java.io.FileInputStream; import java.io.F ...