Java多线程(上)
来源:互联网 发布:sm4密码算法.pdf 编辑:程序博客网 时间:2024/06/15 16:15
创建线程
1. 第一种方式:继承Thread类
步骤:
1) 定义一个类继承Thread
2) 覆写Thread类中的run()方法
3) 调用线程的start()方法——启动线程,调用run()方法
程序示例:
class Demoextends Thread
{
public void run()
{
for(int i = 0; i < 100;i++)
System.out.println("Thread run---- "+ i);
}
}
public classThreadDemo
{
public static void main(String[] args)
{
Demo d = new Demo();
d.start();
for(int i = 0; i < 100;i++)
System.out.println("java thread----"+ i);
}
}
线程都有自己默认的名称,Tread-编号,该编号从0开始。
我们可以自己设置线程名称,staticThread currentThread():获取当前线程对象,
getName():获取线程名称,通过setName()或者构造函数super()进行设置。
class MyThreadextends Thread
{
//private String name;
MyThread(String name)
{
//this.name = name;
super(name);
}
public void run()
{
for(int x = 0; x <50; x++)
{
System.out.println(Thread.currentThread().name+ " run..." + x);
//System.out.println(this.getName()+ " run..." + x);
}
}
}
class ThreadTest
{
public static void main(String[] args)
{
MyThread t01 = newMyThread("one");
MyThread t02 = newMyThread("two");
t01.start();
t02.start();
for(int x = 0; x < 50;x++)
{
System.out.println("mainrun..." + x);
}
}
}
2. 创建线程的第二种方法:
1) 实现Runnable接口,
2) 覆盖它的run(),run()中存放线程要执行的代码
3) 通过Thread类建立线程对象
4) 将Runnable接口子类对象作为实际参数传递给Thread类的构造函数
让线程执行指定对象的run()方法
5) 调用Thread类的start()方法开启线程
两种创建线程的方法(extendsThread 和 implements Runnable)的区别:
实现方式的好处:打破了java单继承的局限性。
程序示例:
class Ticketimplements Runnable
{
private int ticket = 100;//static 一般不用,因为它的生命周期太长
/*
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
*/
/*
*Ticket(String name)
*{
* super(name);
*}
*/
public void run()
{
while(true)
{
if(ticket > 0)
{
System.out.println(Thread.currentThread().getName()+ "...sale : " + ticket--);
}
}
}
}
class TicketTest
{
public static void main(String[] args)
{
Ticket ticket = new Ticket();
//让线程执行指定对象(此处为ticket)的run()方法
Thread t1 = newThread(ticket, "t1");
Thread t2 = newThread(ticket, "t2");
Thread t3 = newThread(ticket, "t3");
t1.start();
t2.start();
t3.start();
}
}
同步
多线程的运行存在安全问题
因为当多条语句操作同一个线程共享数据时,一个线程对多条只执行了一部分,还没执行完,另一个线程就参与进来执行,导致共享数据错误。
解决方法:
对共享数据的多条操作语句,只能让一个线程都执行完,在执行过程中,其他线程不可以参与执行。即同步。
同步的前提:
1) 必须有两个或者两个以上线程
2) 多个线程共用一个锁
同步好处:
解决了多线程安全问题。
同步弊端:
多个线程需要判断锁,较为消耗资源。
1. 同步代码块
synchronized(Object)
{
需要被同步的代码(操作共享数据的代码)
}
对象如同锁,比如火车的卫生间门上的提示。
程序示例:
classTicket implements Runnable//extends Thread
{
private int ticket = 100;
Object obj = new Object();
public void run()
{
while(true)
{
synchronized(obj)//同步代码块
{
if(ticket> 0)
{
try
{
Thread.sleep(10);
}
catch(Exception e)
{
}
System.out.println(Thread.currentThread().getName()+ "...sale : " + ticket--);
}
}
}
}
}
publicclass TicketTest02
{
public static void main(String[] args)
{
Ticket ticket = new Ticket();
Thread t1 = newThread(ticket, "t1");
Thread t2 = newThread(ticket, "t2");
Thread t3 = newThread(ticket, "t3");
t1.start();
t2.start();
t3.start();
}
}
2. 同步函数
同步函数用的锁是 this
程序示例:
需求:某银行有一个金库,两个储户分别存300元,每次存100,存三次
classBank
{
private int sum;//成员变量可以不初始化,默认是0
public synchronized void add(intmoney)//使用synchronized修饰的同步函数
{
sum += money;
try
{
Thread.sleep(10);
}
catch (Exception e)
{
}
System.out.println("sum= " + sum);
}
}
classChest implements Runnable//金库类
{
private Bank bank = new Bank();
public void run()
{
for(int x = 0; x < 3; x++)
{
bank.add(100);//存入100,存三次
}
}
}
publicclass BankDemo
{
public static void main(String[] args)
{
Chest c = new Chest();
//创建两个线程,即两个储户
Thread t1 = new Thread(c)
Thread t2 = new Thread(c);
t1.start();
t2.start();
}
}
3. 静态同步函数使用的锁是:类名.class (不再是this 静态方法中不可以定义this)
静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象,类名.class。该对象的类型是Class
程序示例:
class Ticket implements Runnable
{
privatestatic int ticket = 1000;
booleanflag = true;
publicvoid run()
{
if(flag)
{
while(true)
{
synchronized(Ticket.class)//同步代码块
{
if(0< ticket)
{
try
{
Thread.sleep(10);
}
catch(Exception e)
{
}
System.out.println(Thread.currentThread().getName()+ "....code....." + ticket--);
}
}
}
}
else
{
while(true)
{
show();
}
}
}
publicstatic synchronized void show()//静态同步函数
{
if(0< ticket)
{
try
{
Thread.sleep(10);
}
catch(Exception e)
{
}
System.out.println(Thread.currentThread().getName()+ ".....show..... " + ticket--);
}
}
}
public class StaticSynchronized
{
publicstatic void main(String[] args)
{
Tickettick = new Ticket();
Threadt1 = new Thread(tick, "thrEAd01");
Threadt2 = new Thread(tick, "thrEAd02");
Threadt3 = new Thread(tick, "thrEAd03");
t1.start();
try
{
Thread.sleep(40);
}
catch(Exception e)
{
}
t3.start();
try
{
Thread.sleep(40);
}
catch(Exception e)
{
}
tick.flag= false;
t2.start();
}
}
- Java-----多线程(上)
- Java多线程(上)
- Java 多线程(上)
- java多线程(上)
- 别样JAVA学习(七)多线程上
- Java中多线程总结(上)
- Java基础-多线程学习(上)
- (3)Java多线程之安全问题-上
- java线程实战:多线程下载(上)
- Java基础整理-多线程基础(上)
- Java的多线程(上)
- java多线程问题(上)
- Java多线程同步教程 --上
- java基础教程-多线程编程(上)
- JAVA多线程笔记总结(上)
- java的多线程机制上
- JAVA中多线程知识点《上》
- Java多线程(全)学习笔记(上)
- Redis 起步
- My97DatePicker在Frame中无法打开站点
- 数据库查询优化原则
- 帮助:磁带库卷带失败问题,有熟悉的人帮忙看一下,一起学习
- js刷新页面
- Java多线程(上)
- Hibernate:java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to co
- android滑屏切换界面
- Buffer Cache 原理
- discuz的css hack搞法 妈妈再也不用当心我的兼容性了
- VC2008配置boost库使用正则表达式的步骤
- 第九周上机任务项目3-分数类
- SQLServer DBCC用法
- 自定义 DialogPreference 代碼備份