基本概念
线程是一个程序内部的顺序控制流

Java的线程是通过java.lang.Thread类来实现的。main函数是一个主线程,用户可以通过创建Thread的实例来创建新的线程。每一个线程都必须实现run方法。通过Thread类的start方法来启动一个线程。

两种方式实现,一种是线程类实现Runnable接口;二种就是定义一个Thread的子类并重写其run方法。

public class TestThread1 {public static void main(String args[]) {Runner1 r = new Runner1();r.start();//r.run();//Thread t = new Thread(r);//t.start();for(int i=0; i<100; i++) {System.out.println("Main Thread:------" + i);}}
}//class Runner1 implements Runnable {class Runner1 extends Thread {public void run() {for(int i=0; i<100; i++) {  System.out.println("Runner1 :" + i);}}
}

以下是几个线程控制的基本方法

用stop或者其他方法直接切断线程是很暴力的是很不好的,这里介绍一种比较好的结束线程的办法。巧妙的用到一个flag。

public class TestThread4 {  public static void main(String args[]){Runner4 r = new Runner4();Thread t = new Thread(r);t.start();for(int i=0;i<100000;i++){if(i%10000==0 & i>0)System.out.println("in thread main i=" + i);}System.out.println("Thread main is over");r.shutDown();//t.stop();}
}class Runner4 implements Runnable {private boolean flag=true;public void run() {int i = 0;while (flag==true) {System.out.print(" " + i++);    }}public void shutDown() {flag = false;}
}

线程同步
线程同步这个问题很重要,会衍生很多锁的问题。也是两种方式上锁,一种是直接在方法上上锁,另一种就是锁对象。

public class TestSync implements Runnable {Timer timer = new Timer();public static void main(String[] args) {TestSync test = new TestSync();Thread t1 = new Thread(test);Thread t2 = new Thread(test);t1.setName("t1"); t2.setName("t2");t1.start(); t2.start();}public void run(){timer.add(Thread.currentThread().getName());}
}class Timer{private static int num = 0;public synchronized void add(String name){ //synchronized (this) {num ++;try {Thread.sleep(1);} catch (InterruptedException e) {}System.out.println(name+", 你是第"+num+"个使用timer的线程");//}}
}

死锁
假如两个线程都需要两个资源才能完成,A线程把a资源锁定等待b资源,B线程把b资源锁定等待a资源。这样就会形成死锁,所以我们要把锁定义到最大化就是锁定整个对象,就是专业术语说锁的粒度要尽量大。

public class TT implements Runnable {int b = 100;public synchronized void m1() throws Exception{//Thread.sleep(2000);b = 1000;Thread.sleep(5000);System.out.println("b = " + b);}public void m2() throws Exception{Thread.sleep(2500);b = 2000;}public void run() {try {m1();} catch(Exception e) {e.printStackTrace();}}public static void main(String[] args) throws Exception {TT tt = new TT();Thread t = new Thread(tt);t.start();tt.m2();System.out.println(tt.b);}
}

这个程序段输出的结果是
2000
b = 2000
这段程序也是先进的m2。

package yanning;public class TT implements Runnable {int b = 100;public synchronized void m1() throws Exception{System.out.println(2);//Thread.sleep(2000);b = 1000;Thread.sleep(5000);System.out.println("b = " + b);}public synchronized void m2() throws Exception {System.out.println(1);Thread.sleep(2500);b = 2000;}public void run() {try {m1();} catch(Exception e) {e.printStackTrace();}}public static void main(String[] args) throws Exception {TT tt = new TT();Thread t = new Thread(tt);t.start();tt.m2();System.out.println(tt.b);}
}

这段代码输出的结果是
1
2000
2
b = 1000

package yanning;public class TT implements Runnable {int b = 100;public synchronized void m1() throws Exception{//System.out.println(2);//Thread.sleep(2000);b = 1000;Thread.sleep(5000);System.out.println("b = " + b);}public synchronized void m2() throws Exception {//System.out.println(1);Thread.sleep(2500);b = 2000;}public void run() {try {m1();} catch(Exception e) {e.printStackTrace();}}public static void main(String[] args) throws Exception {TT tt = new TT();Thread t = new Thread(tt);t.start();tt.m2();System.out.println(tt.b);}
}

这一段代码执行结果是
1000
b = 1000
锁是锁住了,但是tt那个线程执行的快一些,先进入了m2。

所以说线程同步是一个很复杂的问题,我们得仔细推敲。而且我个人觉得跟电脑的运行速度还是有关系的。其他线程可以自由访问没有加同步的任何方法,并且会产生数据不一致的现象。如果要保护好某一类的同步对象,必须要对该对象所有的方法考虑加不加同步,加了同步很有可能效率会变低,不加同步很有可能造成数据不一致的现象。

优先级
我的理解就是CPU优先让哪个线程执行嘛,比较单CPU其实是假的多线程,就是因为CPU运算速度比较快,所以就一个线程让你执行一下,就像是多线程在执行一样。

生产者与消费者问题【经典问题】


public class ProducerConsumer {public static void main(String[] args) {SyncStack ss = new SyncStack();Producer p = new Producer(ss);Consumer c = new Consumer(ss);new Thread(p).start();new Thread(c).start();}
}class WoTou {int id; WoTou(int id) {this.id = id;}public String toString() {return "WoTou : " + id;}
}class SyncStack {int index = 0;WoTou[] arrWT = new WoTou[6];public synchronized void push(WoTou wt) {while(index == arrWT.length) {try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}this.notifyAll();       arrWT[index] = wt;index ++;}public synchronized WoTou pop() {while(index == 0) {try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}this.notifyAll();index--;return arrWT[index];}
}class Producer implements Runnable {SyncStack ss = null;Producer(SyncStack ss) {this.ss = ss;}public void run() {for(int i=0; i<20; i++) {WoTou wt = new WoTou(i);ss.push(wt);
System.out.println("生产了:" + wt);try {Thread.sleep((int)(Math.random() * 200));} catch (InterruptedException e) {e.printStackTrace();}           }}
}class Consumer implements Runnable {SyncStack ss = null;Consumer(SyncStack ss) {this.ss = ss;}public void run() {for(int i=0; i<20; i++) {WoTou wt = ss.pop();
System.out.println("消费了: " + wt);try {Thread.sleep((int)(Math.random() * 1000));} catch (InterruptedException e) {e.printStackTrace();}           }}
}

Java基础知识回顾--线程相关推荐

  1. Java基础知识回顾之七 ----- 总结篇

    前言 在之前Java基础知识回顾中,我们回顾了基础数据类型.修饰符和String.三大特性.集合.多线程和IO.本篇文章则对之前学过的知识进行总结.除了简单的复习之外,还会增加一些相应的理解. 基础数 ...

  2. 【Java基础知识回顾篇】之打怪升级Day001

    Java基础知识回顾篇之打怪升级Day001 目录 Java基础知识回顾篇之打怪升级Day001 简介 一.为什么现在主流的是Java8和Java11? 二.简单尝试编写java程序 1.编写一个He ...

  3. Java基础知识回顾之一 ----- 基本数据类型

    前言 在开始工作至今,学习各种各样的技术之中发现自己的很多Java的基础知识都忘了⊙﹏⊙b汗... 而且越是学习越是发现Java基础的重要性,所以准备单独抽一下时间进行Java基础的重新学习.在重新学 ...

  4. Java基础知识回顾之四 ----- 集合List、Map和Set

    前言 在上一篇中回顾了Java的三大特性:封装.继承和多态.本篇则来介绍下集合. 集合介绍 我们在进行Java程序开发的时候,除了最常用的基础数据类型和String对象外,也经常会用到集合相关类. 集 ...

  5. Java基础知识回顾之六 ----- IO流

    前言 在上一篇文章中,回顾了Java的多线程.而在本篇文章中主要介绍Java IO的相关知识. IO的介绍 什么是IO? IO的名称又来是Input与Output的缩写,也就是输入流和输出流.输入流用 ...

  6. Java基础知识回顾之三 ----- 封装、继承和多态

    前言 在上一篇中回顾了java的修饰符和String类,这篇就来回顾下Java的三大特性:封装.继承.多态. 封装 什么是封装 在面向对象程式设计方法中,封装是指一种将抽象性函式接口的实现细节部份包装 ...

  7. Java基础知识回顾-6

    1.遍历Jar/zip文件中的资源 File jar = new File("myfile.jar"); ZipInputStream zis = new ZipInputStre ...

  8. Java基础知识回顾

    1.Java集合 (1).几种集合(List.Set和Map)的区别          JAVA中几种集合(List.Set和Map)的区别   java常用集合总结 Java集合类: Set.Lis ...

  9. java基础知识回顾之javaIO类总结

    java IO体系图 IO流的操作规律总结: 1,明确体系: 数据源:InputStream ,Reader 数据汇:OutputStream,Writer 2,明确数据:因为数据分两种:字节,字符. ...

最新文章

  1. FFT ---- 2021牛客多校第一场 H Hash Function
  2. 93号涨0.86元售6.2元/升 20日油价正式上调
  3. [渝粤教育] 天津现代职业技术学院 餐饮服务实务(翁莉) 参考 资料
  4. asp.net 事件调用事件问题?
  5. Hadoop连载系列之六:Hadoop数据仓库工具Hive
  6. 阿里云云计算 31在线实验--弹性伸缩(AS)初体验
  7. http抓包实践--(五)-常用的操作
  8. 内网穿透软件NPS--客户端NPC SDK交叉编译ARM64位库
  9. C++ 数据结构实战:快速查找
  10. 【统计学】统计学专业术语
  11. nodejs 点击按钮下载_从服务器下载文件使用NodeJS表达
  12. 税务信息化与计算机技术应用开发,税务信息化与计算机技术应用开发工作岗位年度个人工作总结...
  13. 全国城市-拼音-编号Json数据(只城市)
  14. cie1931 python绘制_在cie1931颜色空间python 2.7中绘制色域
  15. iptables场景一(上)
  16. NO7、斐波那契数列(easy不需再刷)
  17. java入门第二季--面向对象实现人类说话,中国人说汉语,美国人说英语
  18. VS2005 制作安装程序
  19. 助力零售业降本增效,零售业相关场景RPA应用
  20. 在element ui中如何自定义el-date-picker的宽度 笔记

热门文章

  1. 流体式布局与响应式布局_将固定像素设计转换为流体比例布局
  2. vue.js ui_UI / UX开发:考虑Vue.js
  3. Node.js 框架设计及企业 Node.js 基础建设相关讨论
  4. 扒一扒那些年我们遇到的奇葩代码
  5. LeetCode:Count Primes
  6. 怎么快速了解自己的MySQL服务器?
  7. SQLite3.8.4.2在Windows平台下的编译和使用
  8. map reduce相关程序
  9. Vista Dynamips模拟器安装
  10. 30万手表推荐_今年六十岁生日,儿子说要送只30万的手表,请问有哪些推荐?...