黑马程序员----多线程基础

/**
* @author Administrator
*
* @description Java多线程编程入门测试类
* @history
*/
// 方法一、继承线程类Thread
class MyThread extends Thread{
public MyThread(String threadName){ // 设置当前线程的名称
currentThread().setName(threadName);
}
public void run(){
System.out.println(Thread.currentThread().getName());
}
}
// 方法二、实现Runnable接口
class MyThread2 implements Runnable{
public void run() {

System.out.println(Thread.currentThread().getName());
}
}
public class SynTestDemo {
/**
*@description
*@param args
*/
public static void main(String[] args) {
// 1、线程的定义、线程和进程的区别、为什么要引入线程等
// 2、 Java实现多线程的方法主要有两种:继承Thread类和实现Runnable接口
// 3、多个线程并发同时访问公共的临界资源的时候需要进行同步处理,过多的同步不当会造成死锁
问题
MyThread t1 = new MyThread("hello-thread");
t1.start(); // 启动线程1
MyThread2 t2 = new MyThread2();
new Thread(t2).start(); // 启动线程2
}
}
/**
* @author Administrator
*
* @description 多线程编程演练例子
* @history
*/
public class SynABCTest {
/**
* @description
* @param args
*/
public static void main(String[] args) {
// 通过具体的例子来加深对多线程的认识
// 问题为:循环打印10遍ABCABC...ABC
PrintThread p1 = new PrintThread(0, "A"); // 参数为线程标志和打印的内容
PrintThread p2 = new PrintThread(1, "B");
PrintThread p3 = new PrintThread(2, "C");
// 启动线程A B C
new Thread(p1).start();
new Thread(p2).start();
new Thread(p3).start();
}

}
// 采用实现接口的方式定义线程类
class PrintThread implements Runnable {
// 标记执行当前应该执行的线程0、 1、 2依次表示A B C
// 定义成静态变量,因为线程各自使用独立的栈
private static int index = 0;
private static Object lock = new Object();
private int key = 0; // 线程标志
private int print = 0; // 打印的次数
private String name; // 打印的内容
public PrintThread(int key, String name) {
this.key = key;
this.name = name;
}
public void run() {
while (this.print < 10) { // 打印的次数
synchronized (lock) {
while (!(this.key == index % 3)) { // 从0开始执行
try {
lock.wait(); // 阻塞掉
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(this.name); // 打印出内容
this.print++; // 当前线程打印次数++
index++; // 线程切换下一个
lock.notifyAll(); // 唤醒其他等待的线程
}
}
}
}
/**
* @author Administrator
*
* @description 死锁模拟测试类
* @history
*/
public class DeadLockTest {
/**
*@description
*@param args*/
public static void main(String[] args) {
// 过多的同步操作可能会造成死锁问题,死锁产生的原因是形成了环路等待
// 通过两个线程对象进行模拟,线程A完成一个操作需要资源1和资源2,线程B也是一样
// 在资源分配的过程中,线程A占用了资源1,等待资源2,此时此刻线程B占用了资源2,等待资源1
DeadThread dt1 = new DeadThread("1", true);
DeadThread dt2 = new DeadThread("2", false);
new Thread(dt1).start(); // 启动线程1
new Thread(dt2).start(); // 启动线程2
}
// 定义静态内部类、类似外部类了
static class DeadThread implements Runnable{
/**
* 定义资源1和资源2 lock1和lock2
*/
private static Object lock1 = new Object();
private static Object lock2 = new Object();
private String name; // 线程名称
private boolean run; // 执行顺序标记
public DeadThread(String name,boolean run){
this.name = name;
this.run = run;
}
@Override
public void run() {
if(this.run){
// 线程1先占用资源1
synchronized(lock1){
try {
System.out.println("thread1 used lock1");
Thread.sleep(3000); // 暂时休眠3秒
} catch (InterruptedException e) {
e.printStackTrace();
}
// 线程1再去申请资源2,此时资源2已经被线程2占用着不放了
synchronized(lock2){
System.out.println("hello dead-lock");
}
}
}else{
// 线程2先占用资源2
synchronized(lock2){
try {
System.out.println("thread2 used lock2");
Thread.sleep(3000); // 线程2暂时休眠3秒
} catch (InterruptedException e) {
e.printStackTrace();
}
// 线程2再去申请资源1,此时资源1已经被线程1占用着不放了
synchronized(lock1){
System.out.println("hello dead-lock");
}
}
}
}
}
}
class MyThread1 implements Runnable {
private boolean flag = true; // 定义标志位
public void run() {
int i = 0;
while (this.flag) {
System.out.println(Thread.currentThread().getName() + "运行, i = "
+ (i++));
}
}
public void stop() {
this.flag = false; // 修改标志位
}
}
/**
* @author Administrator
*
* @description 通过修改标记位停止线程
* @history
*/
public class ThreadStopDemo {
public static void main(String[] args) {
MyThread1 my = new MyThread1();
Thread t = new Thread(my, "线程"); // 建立线程对象
t.start(); // 启动线程
try {
Thread.sleep(50); // 适当地延迟下
} catch (Exception e) {
e.printStackTrace();
}

my.stop();//修改标志位,停止运行

}

}

时间: 2024-10-07 09:45:48

黑马程序员----多线程基础的相关文章

黑马程序员——java基础——多线程

 黑马程序员--java基础--多线程 ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 进程:是一个正在执行中的程序.每一个进程执行都有一个执行顺序.该顺序是一个执行路径,或者叫一个控制单元. 线程:就是进程中的一个独立的控制单元.线程在控制着进程的执行.一个进程中至少有一个线程. 一个进程至少有一个线程在运行,当一个进程中出现多个线程时,就称这个应用程序是多线程应用程序,每个线程在栈区中都有自己的执行空间,自己的方法区.自己的变量.

黑马程序员——Java基础知识之多线程协同

多线程协同 线程间的通讯:对资源的操作动作不同,比如说两个卡车一个拉煤一个装煤,但是他们共享了一个资源. 怎么样把这个资源拿出来?怎样把车装满?这个资源当然是一个类,他里面的组成元素就是对象!!现在我们就要有操作对象的思想了,用对象把这车装满,现在一车装一个对象. 等待唤醒机制: 用的不是sleep是wait.flag标记,这是两人沟通的方式.其实每个标记就要做一次等待或者notify,判断wait,改值notify.线程池.notify唤醒里面的线程,按顺序唤醒.wait和notify必须用在

黑马程序员_JAVA 基础加强学习笔记

一.面向对象 (一)继承  1.继承的好处: (1) 提高了代码的复用性. (2) 让类与类之间产生了关系,提供了另一个特征多态的前提. 注意: 子类中所有的构造函数都会默认访问父类中的空参数的构造函数,因为每一个子类构造内第一行都有默认的语句super();  如果父类中没有空参数的构造函数,那么子类的构造函数内,必须通过super语句指定要访问的父类中的构造函数. 如果子类构造函数中用this来指定调用子类自己的构造函数,那么被调用的构造函数也一样会访问父类中的构造函数. 2.final特点

黑马程序员——Java基础---IO(下)

黑马程序员——Java基础---IO(下) ------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------ 一.概述 Java除了基本的字节流.字符流之外,还提供了File类.properties类.打印流.序列流等和输入输出相关的类,它们能够帮助我们更好的处理信息.下面将对它们进行简单的介绍. 一.正

黑马程序员——Java基础---集合框架工具类

黑马程序员——Java基础<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------ 一.概述 Java为操作Set.List和Map提供了一系列工具类,主要有Collections和Arrays.这两个工具类的特点:类中的方法都是静态的,不需要创建对象,直接使用类名调用即可.Collections:是集合对象

黑马程序员_Java基础加强(下)

8.注解类 注解相当于一种标记,加了注解就等于打上了某种标记,没加就等于没打特殊标记,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记就去干什么事,标记可以加在包.类.字段.方法,方法的参数以及局部变量上. 注解的应用结构图: 为注解增加属性 定义基本类型的属性和应用属性 在注解类中增加String color(); @MyAnnotation(color = "red") 用反射方式获得注解对应的实例对象后,再通过该对象调用属性对应的方法 MyAnno

黑马程序员_Java基础加强(上)

1.静态导入 静态导入是jdk1.5版本以后出现的新特性,一般是指导入静态方法,如:import static java.lang.System.out 是指导入系统输出的静态方法. 例: import static java.lang.System.out //导入java.lang包下的System类的静态方法out public class StaticImport { public static void main(String[] args) { int x=1; x++; out.p

黑马程序员-正则表达式基础

正则表达式是一种描述字符串集的方法,它是以字符串集中各字符串的共有特征为依据的.正则表达式可以用于搜索.编辑或者是操作文本和数据.它超出了 Java 程序设计语言的标准语法,因此有必要去学习特定的语法来构建正则表达式.正则表达式的变化是复杂的,一旦你理解了它们是如何被构造的话,你就能解析或者构建任意的正则表达式了..正则表达式由一些普通字符和一些元字符组成. 普通字符包括大小写的字母和数字,而元字符则具有特殊的含义.在最简单的情况下,一个正则表达式看上去就是一个普通的查找串.例如,正则表达式"a

黑马程序员——java基础---IO(input output)流字符流

黑马程序员——java基础---IO(input output)流字符流 ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- io(input output)流特点: 1,io流用来处理数据之间的传输 2,java对数据的操作是通过流的方式: 3,java用于操作流的对象都在io包中: 4,流按操作数据分为两种:字节流和字符流: 5,流按流向分为:输入流和输出流. 注意:流只能操作数据,而不能操作文件. 3.IO流的常用基类: 1)字节流的抽象