JAVA学习课第二十八届(多线程(七))- 停止-threaded多-threaded面试题

主密钥

/*

* wait 和 sleep 差别?

* 1.wait能够指定时间也能够不指定

* sleep必须指定时间

* 2.在同步中,对CPU的运行权和锁的处理不同

* wait释放运行权,释放锁    sleep释放运行权,不释放锁

*/

//同步里具备运行资格的线程不止一个,可是能得到锁的仅仅有一个,所以能运行的也仅仅有一个

一、停止线程的方式

不可能让线程一直在执行。所以须要让线程停止

1.定义循环结束标记

一般而言,线程执行代码都是循环的,仅仅要控制了循环就能够结束任务

2.使用interrupt(中断)

结束线程的冻结状态。使线程回到执行状态

PS:stop过时了,不用了

第一种方式:(经常使用)

class StopThread implements Runnable
{
	private boolean flag = true;
	public void run()
	{
		while(flag)
		{
			System.out.println(Thread.currentThread().getName()+"---");
		}
	}
	public void ChangeFlag()
	{
		flag = false;
	}
}
public class Main
{
	public static void main(String[] args)
	{
		StopThread s = new StopThread();
		Thread t1 = new Thread(s);
		Thread t2 = new Thread(s);
		t1.start(); t2.start();
		int i = 0;
		while(true)
		{
			if(++i == 20)//i达到20后结束全部线程
			{
				s.ChangeFlag();
				break;
			}
			System.out.println("Main.main"+i);
		}
			System.out.println("Final");
	}
}

缺点:

class StopThread implements Runnable
{
	private boolean flag = true;
	public synchronized void run()
	{
		while(flag)
		{
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO: handle exception
				System.out.println(Thread.currentThread().getName()+"..."+e);
			}
			System.out.println(Thread.currentThread().getName()+"-++--");
		}
	}
	public void ChangeFlag()
	{
		flag = false;
	}
}

主线程结束了。t0 t1直接wait()了。假设线程处于了冻结状态。就无法读取标记,所以就引入了另外一种结束线程的方式

另外一种方式:interrupt

将线程从冻结状态强制恢复到执行状态中。使线程回到具备CPU执行资格的状态。可是会发生中断异常(InterruptException)

class StopThread implements Runnable
{
	private boolean flag = true;
	public synchronized void run()
	{
		while(flag)
		{
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO: handle exception
				System.out.println(Thread.currentThread().getName()+"........."+e);
				flag = false;//注意处理,不加这个会导致线程继续等待。主线程结束t1 t2未结束
			}
			System.out.println(Thread.currentThread().getName()+"-++--");
		}
	}
	public void ChangeFlag()
	{
		flag = false;
	}
}
public class Main
{
	public static void main(String[] args)
	{
		StopThread s = new StopThread();
		Thread t1 = new Thread(s);
		Thread t2 = new Thread(s);
		t1.start(); t2.start();
		int i = 0;
		while(true)
		{
			if(++i == 20)//i达到20后结束全部线程
			{
				//s.ChangeFlag();
				t1.interrupt();
				t2.interrupt();
				break;
			}
			System.out.println("Main.main"+i);
		}
			System.out.println("Final");
	}
}

二、守护线程

setDaemon(boolean)

public class Main
{
	public static void main(String[] args)
	{
		StopThread s = new StopThread();
		Thread t1 = new Thread(s);
		Thread t2 = new Thread(s);
		t1.start();
		t2.setDaemon(true);//守护线程,能够理解为后天线程
		//后天线程的特点:执行和前台线程一样,和CPU抢夺执行权
		//           结束:前台线程必须手动结束,后台线程假设全部的前提线程都结束了,后台线程也跟着结束
		t2.start();
		int i = 0;
		while(true)
		{
			if(++i == 20)//i达到20后结束全部线程
			{
				//s.ChangeFlag();
				t1.interrupt();
				//t2.interrupt();
				break;
			}

			System.out.println("Main.main"+i);
		}
			System.out.println("Final");
	}
}

守护线程简单理解:比方说(英雄联盟)LOL。我方英雄须要守护我方的防御塔,塔没了,守护线程也就不是必需存在了

三、线程的其它方法

1.join()

2.setPriority()

class Demo implements Runnable
{
	public void run()
	{
		for(int i = 0;i<20;i++)
			System.out.println(Thread.currentThread().getName()+"..."+i);
	}
}

public class Main
{
	public static void main(String[] args)throws Exception
	{
		Demo d = new Demo();
		Thread t1 = new Thread(d);
		Thread t2 = new Thread(d);
		t1.start();
		t1.join();//t1线程要申请增加进来。执行。也就是t1不完,t2 和 主线程 就不能执行。
		//暂时假如一个线程,就要用join方法
		t2.start();//假设join放在t2.start()后面,那么主线程仅仅等待t1完毕后执行,而t1和t2互相争夺执行权
		for(int i = 0;i<20;i++)
			System.out.println(Thread.currentThread().getName()+".."+i);
	}
}

优先级:setPriority

class Demo implements Runnable
{
	public void run()
	{
		for(int i = 0;i<20;i++)
			System.out.println(Thread.currentThread().toString()+"..."+i);
	}
}

public class Main
{

	public static void main(String[] args)throws Exception
	{
		Demo d = new Demo();

		Thread t1 = new Thread(d);
		Thread t2 = new Thread(d);
		t1.start();
		t2.start();
		t2.setPriority(Thread.MAX_PRIORITY);
		// Thread.MIN_PRIORITY优先级最小1
		//Thread.MAX_PRIORITY 有效级最大10
		//Thread.NORM_PRIORITY 默认优先级 5
		for(int i = 0;i<20;i++)
			System.out.println(Thread.currentThread()+".."+i);
	}
}

3.线程组

把10个线程放一个组里。假设中断这一组线程。那么这10个线程都中断了

4.yield()暂停当前正在运行的线程,并运行其它线程

class Demo implements Runnable
{
	public void run()
	{
		for(int i = 0;i<20;i++)
			{
			System.out.println(Thread.currentThread().toString()+"..."+i);
		Thread.yield();
			}
	}
}
public class Main
{

	public static void main(String[] args)throws Exception
	{
		new Thread()//线程子类
		{
			public void run()
			{
				for(int i = 0;i<20;i++)
				{
				 System.out.println(Thread.currentThread().getName()+"x = "+i);
				}
			}
		}.start();

		for(int i = 0;i<20;i++)
		{
		 System.out.println(Thread.currentThread().getName()+"y = "+i);
		}
		Runnable r = new Runnable()
		{
			public void run()
			{
				for(int i = 0;i<20;i++)
				{
				 System.out.println(Thread.currentThread().getName()+"z = "+i);
				}
			}
		};
		new Thread(r).start();
	}
}

多线程面试题:

1.

class Text implements Runnable
{
	public void run(Thread t)
	{

	}
}
//是否编译失败?假设失败错误在哪?

失败,没有实现run方法的覆盖

改法一:

abstract class Text implements Runnable
{
	public void run(Thread t)
	{

	}
}

改法二:重载,进行覆盖

class Text implements Runnable
{
	public void run()
	{
		System.out.println("Text.run()1");
	}
	public void run(Thread t)
	{
		System.out.println("Text.run()2");
	}
}

2.

public class Main
{

	public static void main(String[] args)throws Exception
	{

		new Thread(new Runnable()
		{
			public void run() {
				// TODO Auto-generated method stub
				System.out.println("Runnable run");
			}
		})
		{
			public void run()
			{
				System.out.println("Thread run");
			}
		}.start();//这段代码编译能通过吗?假设能打印哪一句
	}
}

打印Thread run

以子类为主,没有子类以父类为主

版权声明:本文博主原创文章,博客,未经同意不得转载。

时间: 2024-11-11 07:40:11

JAVA学习课第二十八届(多线程(七))- 停止-threaded多-threaded面试题的相关文章

java学习笔记 第二篇 核心技术(二)

第十四章 集合类 集合类用来存放对象的引用.继承关系如下图: 14.1 Collection 接口 是层次结构中的根接口,构成Collection的单位称为元素.Collection接口不能直接使用,但该接口提供了添加元素.删除元素.管理数据的方法. Collection接口常用方法: 14.2 List 集合 包括List接口以及List集合的所有实现类.List集合中的元素允许重复,各元素循序就是对象插入的顺序 1.List接口,两个重要方法: get(int index): 获取指定索引位

JAVA学习课第五十八届 — GUI

GUI Graghical User Interface(图形用户接口) java为GUI提供的对象都存在java.awt和java.swing包中 Java的GUI做的的确干只是C++等.不打算浪费过多的时间在这上面 一个简单的窗口演示 public static void main(String[] args){ Frame f = new Frame("新窗口"); f.setLocation(400, 200);//设置窗口的位置 f.setSize(500, 400);//设

JAVA学习课第五十三届 — IO流程(七)File打靶 &amp;amp; Properties设置

一个.锻炼 深度遍历目录 深度遍历非常自然而然想到递归,而递归就非常自然的想到事实上现的底层算法是栈 对指定文件夹下列出全部内容(包括子文件夹的内容) PS:建议不要遍历C盘 import java.io.*; public class Main { public static void main(String[] args) throws IOException { File dir = new File("D:\\ACM集训"); ListAllDemo(dir,0); } pub

java学习日记第二天

hello 大家好 今天是第二天 上一次 简单的写了俩程序,今天继续用程序学习java基础: 今天学习java中的方法,给我感觉相当于C中的函数,如果你不知道C,那你就把这个方法当做一个招 ,可以解决一个问题这样的东西: 其实上次我们也写了一方法 public static void main(String args[])  即我们主函数,我们程序的入口, 现在我们再想创建一个Java Profect ,点开工程然后在src中右击new一个class ,注意类名(Class的名字)首个字母大写,

echo——我的第一堂java学习课

毕业到现在已经有12年了,编程语言也学过C,VB,VB.net ,SAP-ABAP,今年开始学习JAVA,希望多少能学到点东西,对自己将来的工作有帮助. 一.DOS命令 1.rd 删除文件 文件夹 2.md 创建文件夹 3.退出文件夹 cd ../../ 4.进去文件夹 cd 5.一个点 是当前目录,二个点是上级目录 6.创建文件方式之一管道 例1: echo abc>a.txt 作用:在当前路径下创建内容为abc的a.txt 作业一.如何强制删除文件夹 例2:test.bat @echo of

java学习笔记之初识多线程

初识多线程 一.进程的认识: 1.进程的理解: 进程可以理解成正在执行的任务,就是正在运行的程序,进程又分为两种,一种是前台进程,就是我们很直观看见的,另一种是后台进程,就是操作系统启动就有的(系统级的进程),每个进程运行之后都会占用一定的cpu和内存资源: 比如说:我们打开window任务管理器就可以看到有很多的进程,里面有用户开启的,也有操作系统启动的进程 2.进程的调度: 也就是那么多的进程,cpu是怎样运行的呢? 采用时间片轮转法 二.线程认识 1.线程的理解 线程是在进程的内部运行的执

Java学习笔记45(多线程二:安全问题以及解决原理)

线程安全问题以及解决原理: 多个线程用一个共享数据时候出现安全问题 一个经典案例: 电影院卖票,共有100座位,最多卖100张票,买票方式有多种,网上购买.自主售票机.排队购买 三种方式操作同一个共享数据,这时候会出现安全问题: 示例: package demo1; public class Tickets implements Runnable { private int ticket = 100; public void run(){ while(true){ if (ticket>0) {

JAVA学习课第五 — IO流程(九)文件分割器合成器

文件分割器 private static final int SIZE = 1024 *1024; public static void splitFile(File file) throws IOException{ //用读取流关联文件(不确定文件格式) FileInputStream fis = new FileInputStream(file);//源是一个 byte[] by = new byte[SIZE];//定义1M的缓冲区 FileOutputStream fos = null

Java学习笔记五(多线程)

1.介绍 线程能够使程序具有两条和两条以上的可执行的路径,尤其对多核CPU特别的重要. 2.创建线程 1.继承Thread类 一个类直接的继承Thread类的话,此类就具有了线程的能力,接下来只需要重写继承的run()即可. <span style="font-size:18px;">package com.Thread; //定义实现Runnable接口的类 class MyThread11 extends Thread { //实现run方法,指定线程执行的任务 pub