题目一

本质上来说,线程是不可控制的,线程的执行是由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. layui 表格内容显示更改

    在cole 中使用temple 属性进行修改 例: table.render({ elem: '#messageTable' ,id: 'search_table_mId' ,height: 500 ...

  2. CSS文字的跑马灯特效

    上学时同学有个来电带跑马灯的手机,可把我羡慕坏了,可等我买的起手机时,跑马灯不流行了,甚伤萝卜心! 今天就用CSS做个文字的跑马灯特效,缅怀一下本萝卜逝去的青春! 道具:会敲代码的巧手.七窍玲珑心.会 ...

  3. QEMU KVM Libvirt(12): Live Migration

    由于KVM的架构为 Libvirt –> qemu –> KVM 所以对于live migration有两种方式,一种是qemu + KVM自己的方式,一种是libvirt的方式,当然li ...

  4. java并发面试

    1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线程(Daemon)和用户线程(User). 任何线程都可以设置为守护线程和用户线程,通过方法Thread.setDaemon( ...

  5. Nginx限流配置

    电商平台营销时候,经常会碰到的大流量问题,除了做流量分流处理,可能还要做用户黑白名单.信誉分析,进而根据用户ip信誉权重做相应的流量拦截.限制流量.Nginx自身有的请求限制模块ngx_http_li ...

  6. [Swift]LeetCode212. 单词搜索 II | Word Search II

    Given a 2D board and a list of words from the dictionary, find all words in the board. Each word mus ...

  7. [Swift]LeetCode653. 两数之和 IV - 输入 BST | Two Sum IV - Input is a BST

    Given a Binary Search Tree and a target number, return true if there exist two elements in the BST s ...

  8. [Swift]LeetCode979. 在二叉树中分配硬币 | Distribute Coins in Binary Tree

    Given the root of a binary tree with N nodes, each node in the tree has node.val coins, and there ar ...

  9. PHP常用设计模式讲解

    开发中适当的使用设计模式,可以让项目有更易扩展,易维护.低耦合,代码简洁等 单例模式 <?php /** * 单例模式:使类在全局范围内只允许创建一个对象,常用于数据库连接等 */ class ...

  10. Unable to preventDefault inside passive event listener due to target being treated as passive

    Unable to preventDefault inside passive event listener due to target being treated as passive 今天在做项目 ...