概述
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
1)进程:
是一个正在执行中的程序。
每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元。
(2)线程:
就是进程中的一个独立的控制单元。
线程在控制着进程的执行。一个进程中至少有一个线程。
java中体现:java JVM启动的时候,会有一个进程java.exe。该进程中至少有一个线程在负责java程序的执行。
(3)多线程
在java虚拟机启动的时候会有一个java.exe的执行程序,也就是一个进程。该进程中至少有一个线程负责java程序的执行。而且这个线程运行的代码存在于main方法中。该线程称之为主线程。JVM启动除了执行一个主线程,还有负责垃圾回收机制的线程。像种在一个进程中有多个线程执行的方式,就叫做多线程。
(4)多线程的利与弊:
好处:多线程解决了多部分同时运行的问题。
坏处:线程太多,执行效率太低。
(3)如何创建多线程:
如何实现多线程:首先,我们必须指明这个线程所要执行的代码,而这就是在Java中实现多线程我们所需要做的一切!
方法(1):继承 Thread 类,重写 方法 run(),我们在创建Thread 类的子类中重写 run() ,加入线程所要执行的代码即可。
实例:
<pre name="code" class="java">class Demo extends Thread
{
public void run()
{
for(int i=1;i<10;i++)
{
System.out.println("Hello World!");
}
}
public static void main(String[] args)
{
Demo t=new Demo();
t.start();
for(int i=1;i<10;i++)
{
System.out.println("Hello ......World2!");
}
}
}
示例(2)实现runnable接口:
(1)定义实现Runnable接口。
(2)覆盖run方法,将线程的任务代码都封装在run方法中。
(3)通过Thread类创建线程对象,并将runnable接口的子类对象作为thread类构造函数的参数进行传递。
(4)调用start方法开启线程。package 练习2;
public class ThreadDemo {
public static void main(String[]args){
Demo1 d=new Demo1();
Thread t1=new Thread(d);
Thread t2=new Thread(d);
t1.start();
t2.start();
}
}
class Demo1 implements Runnable
{
public void run()
{
for(int i=0;i<20;i++)
{
System.out.println(Thread.currentThread().getName()+"...."+i);
}
}
}
二、两种方式的区别和线程的几种状态
1、两种创建方式的区别
继承Thread:线程代码存放在Thread子类run方法中。
实现Runnable:线程代码存放在接口子类run方法中。
实例(1)使用继承thread类设计售票系统:
package 多线程;
/**
* 题目:继承thread类实现售票系统:
*
* 分析:1、首先继承thread类。
* 2、重写run方法并打印票数;
* 3、启动多线程;
*
* */
public class ThreadDemo {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Ticket windows1=new Ticket();
Ticket windows2=new Ticket();
windows1.start();
windows2.start();
}
}
class Ticket extends Thread
{
private int ticket =100;
//private String name;
public Ticket(){}
public void run()
{
while(ticket>0)
{
if(ticket>0)
System.out.println(Thread.currentThread().getName()+" "+ticket--);
}
}
}
实例二:通过实现Runnable接口实现售票系统:
package 多线程;
/**
* 题目:继承thread类实现售票系统:
*
* 分析:1、首先继承thread类。
* 2、重写run方法并打印票数;
* 3、启动多线程;
*
* */
public class ThreadDemo {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Ticket windows1=new Ticket();
Ticket windows2=new Ticket();
windows1.start();
windows2.start();
}
}
class Ticket extends Thread
{
private int ticket =100;
//private String name;
public Ticket(){}
public void run()
{
while(ticket>0)
{
if(ticket>0)
System.out.println(Thread.currentThread().getName()+" "+ticket--);
}
}
}
public class ThreadDemo {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Ticket t =new Ticket();
Thread windows1=new Thread(t);
Thread windows2=new Thread(t);
windows1.start();
windows2.start();
}
}
class Ticket extends Thread
{
private int ticket =100;
//private String name;
public Ticket(){}
public void run()
{
while(ticket>0)
{
if(ticket>0)
System.out.println(Thread.currentThread().getName()+" "+ticket--);
}
}
}
2、几种状态
被创建:等待启动,调用start启动。
运行状态:具有执行资格和执行权。
临时状态(阻塞):有执行资格,但是没有执行权。
冻结状态:遇到sleep(time)方法和wait()方法时,失去执行资格和执行权,sleep方法时间到或者调用notify()方法时,获得执行资格,变为临时状态。
消忙状态:stop()方法,或者run方法结束。
注:当已经从创建状态到了运行状态,再次调用start()方法时,就失去意义了,java运行时会提示线程状态异常
三、两种方式的区别和线程的几种状态
1、两种创建方式的区别
继承Thread:线程代码存放在Thread子类run方法中。
实现Runnable:线程代码存放在接口子类run方法中。
2、几种状态
被创建:等待启动,调用start启动。
运行状态:具有执行资格和执行权。
临时状态(阻塞):有执行资格,但是没有执行权。
冻结状态:遇到sleep(time)方法和wait()方法时,失去执行资格和执行权,sleep方法时间到或者调用notify()方法时,获得执行资格,变为临时状态。
消忙状态:stop()方法,或者run方法结束。
注:当已经从创建状态到了运行状态,再次调用start()方法时,就失去意义了,java运行时会提示线程状态异常
四、线程安全问题
1、导致安全问题的出现的原因:
当多条语句在操作同一线程共享数据时,一个线程对多条语句只执行了一部分,还没用执行完,另一个线程参与进来执行。导致共享数据的错误。
简单的说就两点:
a、多个线程访问出现延迟。
b、线程随机性 。
注:线程安全问题在理想状态下,不容易出现,但一旦出现对软件的影响是非常大的。
2、解决办法——同步
对多条操作共享数据的语句,只能让一个线程都执行完。在执行过程中,其他线程不可以参与执行。
在java中对于多线程的安全问题提供了专业的解决方式——synchronized(同步)
这里也有两种解决方式,一种是同步代码块,还有就是同步函数。都是利用关键字synchronized来实现。
a、同步代码块
用法:
synchronized(对象)
{需要被同步的代码}
五:同步线程:
(实例一)有同步的代码块:售票系统:
public class ThreadDemo {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Ticket t =new Ticket();
Thread windows1=new Thread(t);
Thread windows2=new Thread(t);
windows1.start();
windows2.start();
}
}
class Ticket extends Thread
{
private int ticket =100;
//private String name;
public Ticket(){}
public void run()
{
while(ticket>=1)
synchronized(this){
try{
Thread.sleep(100);
}catch (InterruptedException e)
{
e.printStackTrace();
}
if(ticket>0)
System.out.println(Thread.currentThread().getName()+" "+ticket--);
}
}
}
六、死锁
当同步中嵌套同步时,就有可能出现死锁现象。
实例(1)死锁:
class LockTest implements Runnable
{
private boolean flag;
LockTest(boolean flag)
{
this.flag=flag;
}
public void run()
{
if(flag)
{
while(true)
{
synchronized(LockClass.locka)//a锁
{
System.out.println(Thread.currentThread().getName()+"------if_locka");
synchronized(LockClass.lockb)//b锁
{
System.out.println(Thread.currentThread().getName()+"------if_lockb");
}
}
}
}
else
{
while(true)
{
synchronized(LockClass.lockb)//b锁
{
System.out.println(Thread.currentThread().getName()+"------else_lockb");
synchronized(LockClass.locka)//a锁
{
System.out.println(Thread.currentThread().getName()+"------else_locka");
}
}
}
}
}
}
//定义两个锁
class LockClass
{
static Object locka = new Object();
static Object lockb = new Object();
}
class DeadLock
{
public static void main(String[] args)
{
//创建2个进程,并启动
new Thread(new LockTest(true)).start();
new Thread(new LockTest(false)).start();
}
}
七:线程之间的沟通:
概述:多线程的主要作用是多个线程处理多个不同的任务,这就必然存在多个线程的协调问题。在运用多线程时,除了可以使用synchronized关键字还可以利用Objiect类中的 notify()、notifyall();wait()方法。让多个同时处理的线程之间能够主动的沟通协调。
八:加入线程:
概述:咋线程操作中,join()方法能够使当前的线程停下来等待另一个线程,就是说让另一一个线程 强制运行,其他线程无法运行,必须等待该线程的运行结束后方能继续运行。
实例::线程加入:
[java] view plaincopy在CODE上查看代码片派生到我的代码片
class Demo implements Runnable{
public void run(){
for (int x=0;x<=10 ;x++ ){
System.out.println(Thread.currentThread().getName()+"...."+x);
}
}
}
class JoinDemo{
public static void main(String[] arsg) throws Exception{
Demo d = new Demo();
Thread t1 = new Thread(d);
Thread t2 = new Thread(d);
t1.start();
t1.join();//主线程执行到t1线程的join方法后,主线程停止,等到t1线程run方法执行结束,主线程才会运行。也就是t1线程加入了主线程
t2.start();
for (int x=0;x<=10 ;x++ ){
System.out.println("main...."+x);
}
System.out.println("over");
}
}
八、停止线程:
实例:
class StopThread implements Runnable
{
private boolean flag =true;
public void run()
{
while(flag)
{
System.out.println(Thread.currentThread().getName()+"....run");
}
}
public void changeFlag()
{
flag = false;
}
}
class StopThreadDemo
{
public static void main(String[] args)
{
StopThread st = new StopThread();
Thread t1 = new Thread(st);
Thread t2 = new Thread(st);
t1.start();
t2.start();
int num = 0;
while(true)
{
if(num++ == 60)
{
t1.interrupt();//清除冻结状态
t2.interrupt();
st.changeFlag();//改变循环标记
break;
}
System.out.println(Thread.currentThread().getName()+"......."+num);
}
System.out.println("over");
}
}
最后
以上就是英俊钢铁侠为你收集整理的黑马程序员——Java(多线程)的全部内容,希望文章能够帮你解决黑马程序员——Java(多线程)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复