Java基础笔记-多线程
线程:
方式一:继承Thread类并且复写run方法.
格式:
class MyThread extends Thread
{
public void run()
{
线程中要运行的代码.
}
}
其步骤为:
1.定义类继承Thread类.
2.复习run方法.---->目的是:用于存储线程中要运行的代码,将自定义的代码存储在run方法中,让线程运行.
3.调用线程的start方法
注意:不是调用run方法.
线程的名字:一般线程有默认的名字,形式为:Thread-编号,编号是从0开始标记的.
也可以获取当前运行线程的名字,用方法:Thread.currentThread().getName()
Thread.currentThread() 是用于获取当前线程的对象.(静态的).
自定义设置线程的名字可以用setName()或者构造函数来设置.
有关线程的继承方式的代码实例和练习:
/*
线程:步骤:
1.定义一个类继承Thread
2.复写类中的润方法
3.创建一个对象(创建一个对象也就创建了一个线程)
4.调用线程的start()方法,调用start方法后,启动了线程,同时也调用了run()方法.
*/
class MyThread extends Thread //第一步
{
public void run() //第二步
{
for(int x = 0; x < 60; x++)
System.out.println("MyThread run!====="+x);
}
} class ThreadDemo
{
public static void main(String args[])
{
MyThread mt = new MyThread();//创建了一个线程. //第三步
mt.start(); // 开启线程并运行该线程的run方法. //第四步
//mt.run(); // 仅仅是对象调用方法,虽然创建了线程,但并未运行线程. for(int x = 0; x < 60; x++)
System.out.println("Hello World!====="+x);
}
}
/* */
class FirstThread extends Thread
{
//private String name;
FirstThread(String name)
{
//this.name = name;
super(name);
}
public void run()
{
for(int i = 1; i <= 50; i++)
{
//System.out.println(this.name+"FirstThread run.====="+i);
System.out.println((Thread.currentThread()==this)+"......"+this.getName()+"FirstThread run.====="+i);
}
}
} class ThreadTest
{
public static void main(String args[])
{
FirstThread ft1 = new FirstThread("First===");
FirstThread ft2 = new FirstThread("Second===");
ft1.start();
ft2.start(); for(int i = 1; i <= 50; i++)
{
System.out.println("mainThread run.====="+i);
}
}
}
/*
售票窗口例子:
多个窗口能够同时卖票.
*/ class Ticket extends Thread
{
private static int ticket = 100; //不用static时候.两个窗口都会同时卖同号的票,即100张票连个窗口都会卖一次(相当于卖了200次)
Ticket(String name)
{
super(name);
}
public void run()
{
while(true)
{
if(ticket>0)
{
System.out.println(Thread.currentThread().getName()+"===卖票===="+ticket--);
}
}
}
} class TicketDemo
{
public static void main(String args[])
{
Ticket t1 = new Ticket("窗口1");
Ticket t2 = new Ticket("窗口2");
t1.start();
t2.start(); }
}
线程的第二种方式:
实现Runnable接口:
格式为:
class MyRunnable implements Runnable
{
public void run()
{
线程中要运行的有关代码.
}
}
其步骤一般为:
1.定义一个类实现Runnable接口.
2.复写Runnable接口中的run方法.
3.通过Thread类来创建一个对象.
4.将Runnable的子类的对象作为实际参数传给Thread类中的构造函数.
5.调用Thread类中的start方法.开启线程,并调用Runnable接口的子类的run方法.(可以理解为run方法又start方法开启调用的)
例如:
class MyRunnable implements Runnable //步骤1
{
public void run() //步骤2
{
S.o.p();
}
}
class RunnableDemo
{
p.s.v.main()
{
MyRunnable mr = new MyRunnable();
Thread t1 = new Thread(mr); //步骤3---4
t1.start(); //步骤5
}
}
/*
售票窗口例子:
多个窗口能够同时卖票.
不使用静态的ticket来完成每个窗口的卖票,且不会卖重复的票.
通过实现Runnable接口来完成. 创建线程的第二种方法:
实现Runnable接口来完成.
步骤:
1.定义一个类实现(implements)Runnable接口
2.复写Runnable接口中的run方法
3.通过Thread类来创建对象
4.将Runnable接口的子类对象作为实际参数传给Thread类中的构造函数.
5.调用Thread类中的start方法开启线程,并调用Runnable接口的子类的run方法.
*/ class Ticket implements Runnable
{
private int ticket = 100; // private static int ticket = 100;
/*
由于Ticket并未继承Thread,该类并没有getName()的方法,因此是不能调用的.
Ticket(String name)
{
super(name);
}
*/
public void run()
{
while(true)
{
if(ticket>0)
{
System.out.println(Thread.currentThread().getName()+"===卖票====="+ticket--);
}
}
}
} class RunnableTicketDemo
{
public static void main(String args[])
{
Ticket t = new Ticket(); //t是共享数据. /*
下面的方法不静态ticket时候会出现卖了200张票的情况,如何不静态 ticket =100,也自定义线程名且不出现卖200张票的情况????
*/
//Ticket tt = new Ticket();
//Ticket ttt = new Ticket();
//Ticket tttt = new Ticket(); //Thread t1 = new Thread(t,"窗口1");
//Thread t2 = new Thread(tt,"窗口2");
//Thread t3 = new Thread(ttt,"窗口3");
//Thread t4 = new Thread(tttt,"窗口4");
/*
下面的代码执行后,Thread.currentThread().getName()获取的是默认的线程名.
*/
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();
}
}
继承方式和实现方式的多态的区别和特点:
实现方式:避免了单继承的局限性.一般定义线程时,建议使用实现方式.
区别:
1.继承Thread:线程代码存放在Thread的子类的run方法中.
2.实现Runnabel:线程的代码存放在Runnable接口的子类的run方法中.
最后是同步代码块,解决了多线程的安全性问题
格式为:
synchronized(对象)
{
需要被同步的代码块.
}
有关实现Runnable接口和同步的示例和练习代码:
/*
多线程的安全问题;
打印出了票数为0.-1.-2等问题. 问题分析,多条语句同时使用同一线程的共享数据时,一个线程只执行了一部分,还未执行完,另一个线程就参与进来执行了,导致共享数据的错误.
在if判断中,当ticket=1时,一个线程进去执行语句后,另一个线程也执行进来.
此时的ticket已经通过ticket--变成了0,从而导致了输出票数为0或者负数的情况.
解决方案:
对操作多条共享数据的语句,让一个线程完全执行完毕后才让另一个线程执行,从而避免这种问题的发生. 同步代码块.关键字:synchronized
格式:
synchronized(对象)
{
需要被同步的代码.
{ 同步的条件:
1.必须是多线程,单线程不能用同步.
2.必须是多个线程使用同一个锁.
必须保证同步中只有一个线程在运行. 同步的好处:解决了多线程的安全性问题.
缺点:每个线程都要判断锁,影响程序运行速度,耗费资源.
*/
class Ticket implements Runnable
{
private int ticket = 100;
Object obj = new Object();
public void run()
{
while(true)
{
synchronized(obj) //obj相当于锁.
{
if(ticket>0)
{
// try{Thread.sleep(10);}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+"===卖票====="+ticket--);
}
}
}
}
} class RunnableTicketSafeDemo
{
public static void main(String args[])
{
Ticket t = new Ticket(); //t是共享数据. 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();
}
}
Java基础笔记-多线程的更多相关文章
- Java基础技术多线程与并发面试【笔记】
Java基础技术多线程与并发 什么是线程死锁? 死锁是指两个或两个以上的进程(线程)在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去,我们就可以称 ...
- 0037 Java学习笔记-多线程-同步代码块、同步方法、同步锁
什么是同步 在上一篇0036 Java学习笔记-多线程-创建线程的三种方式示例代码中,实现Runnable创建多条线程,输出中的结果中会有错误,比如一张票卖了两次,有的票没卖的情况,因为线程对象被多条 ...
- Java学习笔记-多线程-创建线程的方式
创建线程 创建线程的方式: 继承java.lang.Thread 实现java.lang.Runnable接口 所有的线程对象都是Thead及其子类的实例 每个线程完成一定的任务,其实就是一段顺序执行 ...
- Java基础笔记 – Annotation注解的介绍和使用 自定义注解
Java基础笔记 – Annotation注解的介绍和使用 自定义注解 本文由arthinking发表于5年前 | Java基础 | 评论数 7 | 被围观 25,969 views+ 1.Anno ...
- 【转】Java基础笔记 – 枚举类型的使用介绍和静态导入--不错
原文网址:http://www.itzhai.com/java-based-notes-introduction-and-use-of-an-enumeration-type-static-impor ...
- 黑马程序员----java基础笔记中(毕向东)
<p>------<a href="http://www.itheima.com" target="blank">Java培训.Andr ...
- 黑马程序员----java基础笔记上(毕向东)
------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 笔记一共记录了毕向东的java基础的25天课程,分上.中.下 本片为上篇,涵盖前10天课程 1. ...
- Java基础之多线程篇(线程创建与终止、互斥、通信、本地变量)
线程创建与终止 线程创建 Thread类与Runnable接口的关系 public interface Runnable { public abstract void run(); } public ...
- [Java][读书笔记]多线程编程
前言:最近复习java,发现一本很好的资料,<Java2参考大全 (第五版)> Herbert.Schildt.书比较老了,06年的,一些 ...
随机推荐
- 认识Log4j
Log4j是一个非常强大的log记录软件,下面我们就来看看在项目中如何使log4j. 首先当然是得到log4j的jar档,推荐使用1.2.X版,下载地址: http://logging.apache. ...
- Bitmap工具类
一直在使用的一个Bitmap工具类 处理Bitmap和ImageView对象,实现了下面功能: 1.saveBitmap: 把Bitmap对象持久存储到SD卡或手机内存. 2.getViewBitma ...
- apache的keepalive和keepalivetimeout
在APACHE的httpd.conf中,KeepAlive指的是保持连接活跃,类似于Mysql的永久连接.换一句话说,如果将KeepAlive设置为On,那么来自同一客户端的请求就不需要再一次连接,避 ...
- android 获取屏幕尺寸
文章转载自:http://blog.csdn.net/congqingbin/article/details/7474276// 通过WindowManager获取 DisplayMetrics dm ...
- Android使用webService
在android中使用webservice,首先要导入Android webservice支持包 ksoap2-android-assembly-3.3.0-jar-with-dependencies ...
- SQL事务机制
一.事务概念 事务是一种机制.是一种操作序列,它包含了一组数据库操作命令,这组命令要么全部执行,要么全部不执行.因此事务是一个不可分割的工作逻辑单元.在数据库系统上执行并发操作时事务是作为最小 ...
- Method to fix "Naming information cannot be located because the target principal name is incorrect." for AD replication failure
Assume Failure DC FP01 and Working DC DC01 1. Stop the Key Distribution Center (KDC) service on FP01 ...
- 用 alias 给常用命令取个别名
作为一名iOS开发者,很多时候需要用到命令行,有时候一长串的命令实在让人讨厌,特别是一些常用的命令,我们要一遍一遍不厌其烦的去敲键盘.但是老鸟一般都不会这么傻,因为有 alias,通过alias 我们 ...
- PHP搭建(windows64+apache2.4.7+mysql-5.6+php5.5)
现在大部分一键安装包多是32位的,并不支持64位,直接在64位的系统上使用会报错的,所以我这里就来说说windows 64位系统如何建立Apache+PHP+MySQL环境的! 我这里演示用的wind ...
- 初识HTML5
1, 新增canvas标签,允许通过JS在客户端完成2D绘图 2, 新增Video/Audio标签,能取代flash实现媒体播放 3, 新增本地存储功能:localStorage/sessionSto ...