java线程的两种方法,java兑现多线程有两种方法

java实现多线程有两种方法

java实现多线程有两种方法:

一种是继承Thread类

如下面例子:

public class TestThread extends Thread {

//实现多线程方法一:继承Thread类,并重载run方法

public void run(){

//要将一段代码在一个新的线程上运行,该代码应写在run函数中

while(true){

System.out.println(Thread.currentThread().getName() + "is running...");

}

}

}

public class ThreadDemo2 {

public static void main(String[] args) {

//启动一个新的线程,不是直接调用Thread类子类对象的run方法,

//而是调用Thread类子类对象的start方法,Thread类对象的start方法

//将产生新的线程,并在该线程上运行该Thread类对象中的run方法,根据

//多态性 实际上运行的是Thread子类的run方法

TestThread testThread = new TestThread();

testThread.start();

while(true){

System.out.println("main thread is running...");

}

}

}

方法二是:实现接口Runnable中的run函数

如下列所示

//实现多线程方法二:实现Runnable接口,重载run函数,

//大多数情况下,如果只想重写 run() 方法,而不重写其他 Thread 方法,

//那么应使用 Runnable 接口。这很重要,

//因为除非程序员打算修改或增强类的基本行为,否则不应为该类创建子类。

public class TestThread implements Runnable {

public void run() {

// TODO Auto-generated method stub

System.out.println(Thread.currentThread().getName() + "is running......");

}

}

public static void main(String[] args) {

// TODO Auto-generated method stub

TestThread testThread = new TestThread();//创建TestThread类的一个实例

Thread thread = new Thread(testThread);//创建一个Thread类的实例

thread.start();//使线程进入runnable状态

while(true){

System.out.println("main thread is running...");

}

}

2.这两种方法的区别:实现Runnable接口适合多个相同的程序代码访问处理同一资源

如下列所示:

//四个售票窗口售同一中车票,总共有100张,要求这四个售票多线程进行

public class TicketRunnable implements Runnable {

private int tickets = 100;

public void run() {

while(true){

if(tickets > 0){

System.out.println(Thread.currentThread().getName() +

" is saling ticket " + tickets--);

}

}

}

}

public class TicketRunnableDemo {

public static void main(String[] args){

//创建了四个线程,每个线程调用了同一各TicketRunnable对象中run方法,

//访问的是同一个对象中的变量tickets,从而满足了我们的要求。

//实现Runnable接口适合多个相同的程序代码访问处理同一资源

TicketRunnable ticketrunnable = new TicketRunnable();

new Thread(ticketrunnable).start();

new Thread(ticketrunnable).start();

new Thread(ticketrunnable).start();

new Thread(ticketrunnable).start();

}

}

而继承继承Thread类,并重载run方法不能达到此目的

如下所示:

public class TicketThread extends Thread {

private int tickets = 100;

public void run(){

while(true){

if(tickets>0){

System.out.println(Thread.currentThread().getName() +

"is saling ticket " + tickets--);

}

}

}

}

public class TicketThreadDemo {

public static void main(String[] args){

//我们希望的是四个线程共售100,我们创建四个线程

//但结果与我们希望的相反,各个线程各售100张票

new TicketThread().start();

new TicketThread().start();

new TicketThread().start();

new TicketThread().start();

// 如果我们象下面这样写的话,只有一个线程在售票,没有实现四个线程并发售票

// TicketThread ticketThread = new TicketThread();

// ticketThread.start();

// ticketThread.start();

// ticketThread.start();

// ticketThread.start();

}

}

3.后台线程

public class DaemonTest {

public static void main(String[] args){

TicketRunnable ticketRunnable = new TicketRunnable();

Thread thread = new Thread(ticketRunnable);

thread.setDaemon(true);//将此线程设置为后台线程,当进程中只有后台线程时,进程就会结束

thread.start();

}

}

5. 线程同步

在上面的售票程序中,线程可能是不安全的,

比如我们修改一下:

public class ThreadRunnable implements Runnable{

private int tickets = 100;

public void run() {

while(true){

if(tickets > 0){

try{

Thread.sleep(10);//使该线程暂停,

}catch(Exception e){

System.out.println(e.getMessage());

}

System.out.println(Thread.currentThread().getName() +

" is saling ticket " + tickets--);

}

}

}

}

再次测试时,发现可能会打印-1 -2 这样的ticket

所以我们要修改一下,使该程序是线程安全的,

public class TicketSynch implements Runnable{

private int tickets = 100;

String str = new String("");//此对象放在run函数之外

public void run(){

while(true){

synchronized(str){//同步代码块

if(tickets > 0){

try{

Thread.sleep(10);

}

catch(Exception e){

System.out.println(e.getMessage());

}

System.out.println(Thread.currentThread().getName()

+" is saling ticket " + tickets--);

}

}

}

}

}

但是 同步以牺牲程序的性能为代价

5. 同步函数

public class SynchMethod implements Runnable{

private int tickets = 100;

public void run(){

while(true){

sale();

}

}

public synchronized void sale(){

if(tickets > 0){

try{

Thread.sleep(10);

}catch(Exception e){

System.out.println(e.getMessage());

}

System.out.println(Thread.currentThread().getName()

+ "is saling ticket " + tickets--);

}

}

}

public static void main(String[] args){

//创建了四个线程,每个线程调用了同一各TicketRunnable对象中run方法,

//访问的是同一个对象中的变量tickets,从而满足了我们的要求。

//实现Runnable接口适合多个相同的程序代码访问处理同一资源

SynchMethod synchMethod = new SynchMethod();

new Thread(synchMethod).start();

new Thread(synchMethod).start();

new Thread(synchMethod).start();

new Thread(synchMethod).start();

}

6.代码块和函数间的同步

public class MethodAndBlockSyn implements Runnable{

private int tickets = 100;

String str = new String("");

public void run(){

if(str.equals("method")){

while(true){

sale();

}

}

else{

synchronized(str){//同步代码块

if(tickets > 0){

try{

Thread.sleep(10);

}

catch(Exception e){

System.out.println(e.getMessage());

}

System.out.println(Thread.currentThread().getName()

+" is saling ticket " + tickets--);

}

}

}

}

public synchronized void sale(){

if(tickets > 0){

try{

Thread.sleep(10);

}catch(Exception e){

System.out.println(e.getMessage());

}

System.out.println(Thread.currentThread().getName()

+ "is saling ticket " + tickets--);

}

}

}

public static void main(String[] args){

MethodAndBlockSyn test = new MethodAndBlockSyn();

new Thread(test).start();// 这个线程调用同步代码块

try{

Thread.sleep(1);//让线程等待100ms 是为了让该线程得到CPU

//避免该线程未得到CPU就将str设置为method,从而使此线程也是调用同步函数

}catch(Exception e)

{

}

test.str = new String("method");

new Thread(test).start();//这个线程调用同步函数

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值