黑马程序员-多线程
来源:互联网 发布:网络神助攻什么意思 编辑:程序博客网 时间:2024/05/17 07:55
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
创建线程的两种方式:
继承Thread类,用代码体现:
public class MyThread extends Thread
{
public void run()
{
for(int x=0; x<100; x++)
{
System.out.println(getName()+"---"+"hello"+x);
}
}
}
public MyThreadTest
{
public static void main(String[] args)
{
MyThread my1 = new MyThread();
MyThread my2 = new MyThread();
my1.start();
my2.start();
}
}
实现Runnable接口
1.定义类实现Runnable接口
2.覆盖Runnable接口中的run方法
用代码体现
public class MyRunnable implements Runnable
{
public void run()
{
for(int x=0; x<100; x++)
{
System.out.println(Thread.currentThread().getName
()+"---"+"hello"+x);
}
}
}
public class MyRunnableTest
{
public static void main(String[] args)
{
MyRunnable my = new MyRunnable();
Thread t1 = new Thread(my);
Thread t2 = new Thread(my);
t1.start();
t2.start();
}
}
注意:复写run方法的目的是将自定义的代码存储在run方法中,让线程运行
将线程要运行的代码存放在该run方法中
3.通过Thread类建立线程对象
4.通过Runnable接口的子类对象作为实际参数传递给Thread类的构造函数
为什么呢?因为自定义的run方法所属的对象是Runnable接口的子类对象,所以要
让线程去指定指定对象的run方法。就必须明确该run方法所属对象
5.调用Thread类的start方法开启线程并调用Runnable接口子类的run方法
start方法有两个作用:
一是启动线程,二是调用run方法
线程有自己默认的名称:
格式:Thread-编号,编号从0开始。
static Thread currentThread():获取当前线程对象
getName():获取线程名称
设置线程名称:setName或者构造函数
实现方式和继承方式有什么区别呢?
实现方式好处是:避免了单继承的局限性,建议使用它
继承方式:线程代码存放在Thread子类run()方法中
实现方式:存在接口的子类的run方法中
线程安全:
我们先来看段代码:
package thread;
public class TicketsRunnable implements Runnable
{
private int tickets=200;
public void run()
{
while(true)
{
if(tickets>0)
{
System.out.println(Thread.currentThread().getName()+"....sale:"+tick--);
}
}
}
}
package thread;
public class TicketDemo
{
public static void main(String[] args)
{
TicketsRunnable t=new TicketsRunnable();
Thread t1=new Thread(t);
Thread t2=new Thread(t);
Thread t3=new Thread(t);
Thread t4=new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
分析:
在判断中,假如tickets大于1,满足条件,所以Thread-1准备去执行,但是有可能出现一种情况,就是Thread-1
刚判断完正要执行的时候,但是被线程Thread-2给抢去了,而Thread-2正准备要执行,但是被Thread-3抢去了,Thread-3正要准备
去执行的时候,但是被Thread-4给抢去了,这四个全部挂着,但是它们都有执行的资格,假设当Thread-2,Thread-3,Thread-4全部挂着的时候
切换到Thread-1,它就买到1号票了,其他的线程因为不要再判断了,所以他们买到的票tick--就分别是0,-1,-2张错票,这显然不对,所以这里线程不安全。
造成这个问题的原因:
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,
另一个线程参与进来执行,导致共享数据的错误
解决办法:
对多条操作共享数据的语句,只能让一个都执行完,在执行过程中,其他线程不能参与进来
Java对于多线程安全问题使用同步代码块来解决:
synchronized(对象)
{
需要被同步的代码
}
哪些语句正在操作共享数据,那哪些代码块就需要被同步,如下代码所示:
package thread;
public class TicketetsRunnable implements Runnable
{
private int tickets=1000;
Object obj=new Object();
public void run()
{
while(true)
{
synchronized(obj)
{
if(tick>0)
{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread().getName()+"....sale:"+(tickets--));
}
}
}
}
}
同步代码块的原理:
用锁的思想去理解
对象如同锁,持有锁的线程可以在同步中执行,没有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。
同步的前提:
1.必须要有两个或者两个以上的线程
2.必须是多个线程使用同一个锁
必须保证同步中有一个线程在运行就可以了
弊端:多个线程需要判断锁,较为消耗资源
多线程-同步函数:
如何同步?
1.明确哪些代码是多线程运行代码
2.明确共享数据
3.明确多线程运行代码中哪些语句是操作共享数据的
在函数的返回值前面加上synchronized,它就变成同步函数了
同步函数用的是哪一个锁呢?
函数需要被对象调用,函数都有一个所属对象的引用,那就是this
所以同步函数使用的锁是this。
如果同步函数被静态修饰后,使用的锁是什么呢?
通过验证,发现不是this。因为静态方法中也不可以定义this。
静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象,所以它的锁可以用字节码文件对象
格式:类名.class。
该对象的类型是Class.
单例设计模式:
饿汉式:
class Single
{
private static final Single s=new Single();
private Single(){}
public static Single getInstance()
{
return s;
}
}
懒汉式:
class Single
{
private static final Single s=null;
private Single(){}
public static synchronized Single getInstance()
{
if(s==null)
s=new Single();
return s;
}
class SingleDemo
{
public static void main(String[] args)
{
System.out.println("Hello World");
class Single2
{
private static final Single2 s=null;
private Single2(){}
public static Single getInstance()
{
if(s==null)
{
synchronized(Single2.class)
{
if(s==null)
s=new Single();
return s;
}
class SingleDemo
{
public static void main(String[] args)
{
System.out.println("Hello World");
懒汉式面试经常问到。
第二种方式效率提高了。
单例设计模式涉及的知识点必须要会!。
线程间通信,其实就是多个线程在操作同一个资源。
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
- 黑马程序员 多线程
- 黑马程序员:多线程
- 黑马程序员-java多线程
- 黑马程序员--java 多线程
- 黑马程序员_java多线程
- 黑马程序员-java多线程
- 黑马程序员_多线程
- 黑马程序员 多线程
- 黑马程序员_JAVA多线程
- 黑马程序员—多线程
- 黑马程序员- 多线程
- 黑马程序员_多线程
- 黑马程序员--多线程
- 黑马程序员_多线程
- 黑马程序员--Java多线程
- 黑马程序员---多线程
- 黑马程序员__多线程
- 黑马程序员_多线程
- 我所在的团队
- 微信首次关注推送消息
- 庞果英雄会-整数问题
- iscroll
- 黑马程序员_ArrayList的学习
- 黑马程序员-多线程
- JSTL标签库___(1).核心标签库
- 【1】Java垃圾回收机制
- 场地通推出2.0 打造大学会务场地预定新平台
- 伟大,就是管理自己
- 编写高质量的Objective-C代码
- FTP 550 Permission denied 只能读文件夹,没法创建,删除及上传文件
- 使用PowerShell脚本部署定时器到MOSS2010
- 通信概念GSM和TETRA术语