黑马程序员——————java中的多线程
来源:互联网 发布:linux ftp修改访问目录 编辑:程序博客网 时间:2024/06/10 09:46
------- android培训、java培训、期待与您交流! ----------
创建线程的两种方式:
Thread类中的两个最主要的方法:
(1)run()—包含线程运行时所执行的代码,即线程需要完成的任务,是线程
执行体。
(2)start()—用于启动线程
1、通过继承Thread类来创建并启动多线 程的步骤:
(1)定义Thread类的子类,并覆盖该类的run()方法。
(2)创建Thread子类的实例,即创建线程对象。
(3)用线程对象的start()方法来启动该线程。
示例代码:
public class Thread1 extends Thread{
public void run(){
System.out.println(this.getName());
}
public static void main(String args[]){
System.out.println(Thread.currentThread().getName());
Thread1 thread1 = new Thread1();
Thread1 thread2 = new Thread1();
thread1.start();
thread2.start();
}
}
2、实现Runnable接口创建线程类
实现Runnable接口的类必须使用Thread类的实例才能创建线程。通过实现Runnable接口来创建并启动多线程的步骤:
(1)定义Runnable接口的实现类,并实现该接口的run()方法。
(2)创建Runnable实现类的实例,然后将该实例作为参数传入Thread类的构造方法来创建Thread对象。
(3)用线程对象的start()方法来启动该线程。
public class MyRunnable implements Runnable{
public void run(){
System.out.println(Thread.currentThread().getName());
}
public static void main(String args[]){
MyRunnable r1 = new MyRunnable();
MyRunnable r2 = new MyRunnable();
MyRunnable r3 = new MyRunnable();
Thread thread1 = new Thread(r1,"MyThread1"); //创建线程时为其命名
Thread thread2 = new Thread(r2);
thread2.setName("MyThread2"); //通过setName()方法为线程命名
Thread thread3 = new Thread(r3); //不命名的话系统会给线程以默认的名字
thread1.start();
thread2.start();
thread3.start();
}
}
三、两种创建线程方式的比较
采用继承Thread类方式:
(1)优点:编写简单,如果需要访问当前线程,无需使用Thread.currentThread()方法,直接使用this,即可获得当前线程。
(2)缺点:因为线程类已经继承了Thread类,所以不能再继承其他的父类(即会受到java单继承的局限)。
采用实现Runnable接口方式:
(1)优点:线程类只是实现了Runable接口,还可以继承其他的类。在这种方式下,可以多个线程共享同一个目标(target)对象,
所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU代码和数据分开,形成清晰的模型,较好地体现了
面向对象的思想。
(2)缺点:编程稍微复杂,如果需要访问当前线程,必须使用Thread.currentThread()方法。
提示:在实际开发中,一般采用实现Runnable接口的方式来创建线程类,因为它具有更好的灵活性和可扩展性。
线程中的同步和互斥:
下面我们来总结一下synchronized语句(同步代码块儿),
synchronized方法(同步方法)以及静态同步方法的一些知识
public class TraditionalThreadSynchyonized {
public static void main(String[] args) {
final Outputer outputer=newOutputer();
new Thread(new Runnable(){
public void run()
{
while(true)
{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
outputer.output1("liuhongjian");
}
}
}).start();
new Thread(new Runnable(){
public void run()
{
while(true)
{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
outputer.output2("LANJIAOJIAOLANJIAOJIAOLANJIAOJIAO");
}
}
}).start();
new Thread(new Runnable(){
public void run()
{
while(true)
{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
outputer.output3("-----liuhongjian-------");
}
}
}).start();
}
}
class Outputer
{
Public void output1(String name)
{
int len=name.length();
synchronized (Outputer.class) {//同步代码块儿的示例
for(int i=0;i<len;i++)
{
System.out.print(name.charAt(i));
}
System.out.println();
}
}
public synchronized void output2(String name)//同步函数的示例
{
int len=name.length();
for(int i=0;i<len;i++)
{
System.out.print(name.charAt(i));
}
System.out.println();
}
//静态同步函数示例
public static synchronized void output3(String name)
{
int len =name.length();
for(int i=0;i<len;i++)
{
System.out.print(name.charAt(i));
}
System.out.println();
}
}
以上代码是验证:同步函数用的是this锁,静态同步函数用的
是此静态同步函数所在的类的字节码对象锁即Outputer.class
而同步代码块儿synchronized(object obj)即他所用的锁是人
为指定的。要实现互斥必须保证用的是同一把锁!!
线程间共享数据:
这是把资源封装成一个Resouce类,在不同的Runnable中实现互斥
和线程间的通信的代码示例:
class Resouce
{
private String name;
private String sex;
boolean flag=true;
public void setName(String name)
{
this.name=name;
}
public String getName()
{
return this.name;
}
public void setSex(String sex)
{
this.sex=sex;
}
public String getSex()
{
return this.sex;
}
}
class Inputer implements Runnable
{
private Resouce r;
Inputer(Resouce r)
{
this.r=r;
}
public void run()
{
int x=0;
while(true)
{
synchronized(r)
{
if(r.flag)
{
try{r.wait(); }
catch (Exception e){}
}
if(x==0)
{
r.setName("zhangsan");
r.setSex("man");
}
else
{
r.setName("丽丽");
r.setSex("女");
}
x=(x+1)%2;
r.flag=true;
r.notify();
}
}
}
}
class Outputer implements Runnable
{
private Resouce r;
Outputer (Resouce r)
{
this.r=r;
}
public void run()
{
while(true)
{
synchronized(r)
{
if(!r.flag)
{
try{r.wait(); }
catch (Exception e){}
}
System.out.println(r.getName()+
"....."+r.getSex());
r.flag=false;
r.notify();
}
}
}
}
class ThreadShareData2
{
public static void main(String[] args)
{
Resouce r=new Resouce();
Outputer out=new Outputer(r);
Inputer input=new Inputer(r);
new Thread(out).start();
new Thread(input).start();
}
}
------- android培训、java培训、期待与您交流! ----------- 黑马程序员——java中的多线程
- 黑马程序员——java中的多线程
- 黑马程序员——Java中的多线程
- 黑马程序员—java多线程
- 黑马程序员—JAVA多线程
- 黑马程序员—java多线程
- 黑马程序员—Java多线程
- 黑马程序员—java多线程
- 黑马程序员—Java多线程
- 黑马程序员_ JAVA学习日记—JAVA中的多线程
- 黑马程序员——浅谈java中的多线程
- 黑马程序员——java中的多线程编程
- 黑马程序员——java中的多线程(一)
- 黑马程序员——java中的多线程(二)
- 黑马程序员—— c#中的多线程
- 黑马程序员——多线程中的安全问题 :
- 黑马程序员—多线程
- 黑马程序员—多线程
- ios20-播放音频文件
- 选项卡 TabHost
- : Package requirements (libgnomeui-2.0 >= 2.14
- 【jiasuba】内存碎片不用愁 小巧的整理内存软件
- hadoop 网络界面
- 黑马程序员——————java中的多线程
- QThread与其他线程间相互通信,emit,发射信号
- munmap
- utuntu 主题颜色设置
- QT:子窗口嵌入到父窗口,子窗口跟随父窗口 qdialog,qwidget
- 内网IP建ftp服务器的完全攻略
- linux kernel学习笔记(一)
- PostThreadMessage 例子
- Shell编程之实现一个BACnet设备的多种属性