题目一

本质上来说,线程是不可控制的,线程的执行是由CPU资源分配决定的,我们无法干预系统CPU的资源分配,但我们可以增加条件来让线程按照我们的预想顺序来执行。

比如。如果当前的执行的线程不满足我们所定的条件,那么就让CPU重新进行资源的分配,直到资源分配给我们所需要的某个线程

题目说明

编写一个线程类(只有一个类),创建三个线程实例:A线程对象、B线程对象、C线程对象;A线程完成打印“A”, B线程完成打印“B”, C线程完成打印“C”;按照ABC,ABC,ABC……这样来输出。

思路

创建一个存放char的类,以线程名和char的数值为条件,从而控制指定的线程执行

如果单单只靠线程名,不能保证第一次运行的线程是A,线程调用start方法只是进入到就绪状态,需要获得CPU资源才能执行

代码

MyChar.java

package HomeWork2;

/**
* @author StarsOne
* @date Create in 2019-4-9 0009 19:53:39
* @description
*/
class MyChar {
private char c = 'A'; public MyChar() { } public char getC() {
return c;
} public void setC(char c) {
this.c = c;
}
}

PrintThread.java

package HomeWork2;

/**
* @author StarsOne
* @date Create in 2019-4-9 0009 19:53:27
* @description
*/
class PrintThread extends Thread {
private MyChar myChar ; public PrintThread(String name, MyChar myChar) {
super(name);
this.myChar = myChar;
setDaemon(true);//设置为守护进程,主线程停止,当前的子线程也停止
} @Override
public void run() {
while (true) {
synchronized (myChar) {
if (getName().charAt(0) == 'A' && myChar.getC() == 'A') {
System.out.print("A");
myChar.setC('B');//修改mychar里面值,使得线程按指定顺序执行
}else if (getName().charAt(0) == 'B' && myChar.getC() == 'B'){
System.out.print("B");
myChar.setC('C');
}else if (getName().charAt(0) == 'C' && myChar.getC() == 'C'){
System.out.print("C,");
myChar.setC('A');
}
}
try {
sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
} }
}
public static void main(String[] args) {
MyChar myChar = new MyChar();
//注意这里,某个线程传入的都是同一个对象mychar
new PrintThread("A", myChar).start();
new PrintThread("C", myChar).start();
new PrintThread("B", myChar).start(); //主线程休眠
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

题目二

题目说明

3.写两个线程,一个线程打印152,另一个线程打印AZ,打印顺序是12A34B...5152Z;

思路

  • 两个线程,NumberPrintThreadCharPrintThread,前者打印数字,后者打印字符
  • 需要一个CharFlag类,其中有个flag标志,标志接下来要打印数字还是字符

CharFlag.java

package HomeWork3;

/**
* @author StarsOne
* @date Create in 2019-4-9 0009 20:37:49
* @description
*/
class CharFlag {
private boolean flag = false;//默认为false,因为先输出数字 public boolean isFlag() {
return flag;
} public synchronized void changeFlag() {
this.flag = !flag;
}
}

CharPrintThread.java

package HomeWork3;

/**
* @author StarsOne
* @date Create in 2019-4-9 0009 20:37:09
* @description
*/
class CharPrintThread extends Thread {
private CharFlag charFlag; public CharPrintThread(CharFlag charFlag) {
this.charFlag = charFlag;
} private char c = 'A';
@Override
public void run() {
while (c <= 'Z') {
if (charFlag.isFlag()) {
System.out.print(c+" ");//为了好看,加了个空格
charFlag.changeFlag();
c++;//注意这个递增的位置
} }
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

NumberPrintThread.java

package HomeWork3;

/**
* @author StarsOne
* @date Create in 2019-4-9 0009 20:37:09
* @description
*/
class NumberPrintThread extends Thread {
private int num =1;
private CharFlag charFlag; public NumberPrintThread(CharFlag charFlag) {
this.charFlag = charFlag;
} @Override
public void run() {
//num到52结束输出
while (num<=52) {
if (!charFlag.isFlag()) {
System.out.print(num);
if (num % 2 == 0) {
charFlag.changeFlag();
}
num++;//注意这个递增的位置
} }
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

Test.java

package HomeWork3;

/**
* @author StarsOne
* @date Create in 2019-4-9 0009 20:45:14
* @description
*/
class Test {
public static void main(String[] args) {
final CharFlag charFlag = new CharFlag();
new CharPrintThread(charFlag).start();
new NumberPrintThread(charFlag).start();
}
}

PS:不知道出现了什么bug,多次运行后会输出一部分之后就没有输出了,但是程序仍然在执行,似乎是死锁问题?

上面的代码中,出现了死锁问题,因为sleep方法放在了while循环的外头,两个while循环,都会对flag就行修改,获取的方法不是使用同步关键字修饰,所以就会造成死锁问题

解决方法:

把sleep方法放在while循环中,或者把getFlag方法用同步关键字修饰

Java 学习笔记 线程控制的更多相关文章

  1. Java学习笔记 线程池使用及详解

    有点笨,参考了好几篇大佬们写的文章才整理出来的笔记.... 字面意思上解释,线程池就是装有线程的池,我们可以把要执行的多线程交给线程池来处理,和连接池的概念一样,通过维护一定数量的线程池来达到多个线程 ...

  2. JAVA学习笔记16——控制线程

    Java的线程支持提供了一些便捷的工具方法,通过这些便捷的工具方法可以很好地控制线程执行.   join线程 Thread提供了让一个线程等待另一个线程完成的方法——join().当在某个线程执行流中 ...

  3. Java学习笔记--线程day01

    线程的概念:一个线程是进程的顺序执行流: 同类的多个线程共享一块内存空间和一组系统资源,线程本身有一个供程序执行时的堆栈.线程在切换时负荷小,因此,线程也被称为轻负荷进程.一个进程中可以有多个线程. ...

  4. Java学习笔记-流程控制

    在Java中,最常见的就是顺序结构,另外,还有其他的一些的结构,选择,循环等,这些程序结构的加入,使得程序代码更有选择性 判断结构 if语句 三种格式: if(条件表达式) { 执行语句; } if( ...

  5. java学习笔记 - 线程池(一)

    线程池(Thread Pool):把一个或多个线程通过统一的方式进行调度和重复使用的技术,避免了因为线程过多而带来使用上的开销 优点:(面试题)可重复使用已有线程,避免对象创建.消亡和过度切换的性能开 ...

  6. java学习笔记 线程的实现与同步

    2019.4.2 线程实现的两种方式 继承线程,复写其中的run方法 实现runnable接口,复写run方法 使用: MyThread target = new MyThread(); new Th ...

  7. Java学习笔记——线程

    线程: 定义:线程是程序内的一个单一的顺序控制流程,也被称为“轻型进程(lightweight process)” 或“执行上下文(execution context )” 线程用于分隔任务 线程类似 ...

  8. java学习笔记15--多线程编程基础2

    本文地址:http://www.cnblogs.com/archimedes/p/java-study-note15.html,转载请注明源地址. 线程的生命周期 1.线程的生命周期 线程从产生到消亡 ...

  9. Java学习笔记-多线程-创建线程的方式

    创建线程 创建线程的方式: 继承java.lang.Thread 实现java.lang.Runnable接口 所有的线程对象都是Thead及其子类的实例 每个线程完成一定的任务,其实就是一段顺序执行 ...

随机推荐

  1. 初次接触之R语言

    一.什么是R? 最受欢迎的数据分析和可视化平台之一. 其他分析平台:Excel.SPSS.SAS 二.为什么选择R? 免费.支持WINDOWS/MAC OS/Linux. 开源

  2. python语法_装饰器

    装饰器的知识点储备: 1 作用域 2 高阶函数 3 闭包 内部函数,对外部作用作用域的变量进行了引用,该内部函数就认为是闭包, def outer(): x=10 def inner(): print ...

  3. JavaScript基础系列

    JavaScript基础系列 JavaScript是一种基于对象和事件驱动的客户端脚本语言. JavaScript的注释 // 单行 /**/ 多行注释 JavaScript变量,函数名和操作符都是区 ...

  4. [Swift]LeetCode13. 罗马数字转整数 | Roman to Integer

    Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M. Symbol Value I 1 ...

  5. [Swift]LeetCode228. 汇总区间 | Summary Ranges

    Given a sorted integer array without duplicates, return the summary of its ranges. Example 1: Input: ...

  6. layui.table图片显示不全和404问题

    1.图片显示不全 在使用layui.table组件中,加载的图片显示不全,需重新定义CSS如下: .layui-table-cell{ height: auto!important; white-sp ...

  7. HTTPS 到底加密了什么?

    关于 HTTP 和 HTTPS 这个老生常谈的话题,我们之前已经写过很多文章了,比如这篇<从HTTP到HTTPS再到HSTS>,详细讲解了 HTTP 和 HTTPS 的进化之路,对的没错, ...

  8. WebSocket(4)---实现定时推送比特币交易信息

    实现定时推送比特币交易信息 实现功能:跟虚拟币交易所一样,时时更新当前比特币的价格,最高价,最低价,买一价等等...... 提示:(1)本篇博客是在上一遍基础上搭建,上一篇博客地址:[WebSocke ...

  9. qt实现头像上传功能

    想必大家都使用过qt的自定义头像功能吧,那么图1应该不会陌生,本片文章我就是要模拟一个这样的功能,虽然没有这么强大的效果,但是能够满足一定的需求. 图1 qq上传图片 首先在讲解功能之前,我先给出一片 ...

  10. C#版(打败99.28%的提交) - Leetcode 347. Top K Frequent Elements - 题解

    版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...