「java有序线程」java产生线程

博主:adminadmin 2023-01-01 04:45:09 806

本篇文章给大家谈谈java有序线程,以及java产生线程对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

如何创建并运行Java线程

Java线程类也是一个object类,它的实例都继承自java.lang.Thread或其子类。 可以用如下方式用java中创建一个线程:

Tread thread = new Thread();

执行该线程可以调用该线程的start()方法:

thread.start();

在上面的例子中,我们并没有为线程编写运行代码,因此调用该方法后线程就终止了。

编写线程运行时执行的代码有两种方式:一种是创建Thread子类的一个实例并重写run方法,第二种是创建类的时候实现Runnable接口。接下来我们会具体讲解这两种方法:

创建Thread的子类

创建Thread子类的一个实例并重写run方法,run方法会在调用start()方法之后被执行。例子如下:

public class MyThread extends Thread {

public void run(){

System.out.println("MyThread running");

}

}

可以用如下方式创建并运行上述Thread子类

MyThread myThread = new MyThread();

myTread.start();

一旦线程启动后start方法就会立即返回,而不会等待到run方法执行完毕才返回。就好像run方法是在另外一个cpu上执行一样。当run方法执行后,将会打印出字符串MyThread running。

你也可以如下创建一个Thread的匿名子类:

Thread thread = new Thread(){

public void run(){

System.out.println("Thread Running");

}

};

thread.start();

当新的线程的run方法执行以后,计算机将会打印出字符串”Thread Running”。

实现Runnable接口

第二种编写线程执行代码的方式是新建一个实现了java.lang.Runnable接口的类的实例,实例中的方法可以被线程调用。下面给出例子:

public class MyRunnable implements Runnable {

public void run(){

System.out.println("MyRunnable running");

}

}

为了使线程能够执行run()方法,需要在Thread类的构造函数中传入 MyRunnable的实例对象。示例如下:

Thread thread = new Thread(new MyRunnable());

thread.start();

当线程运行时,它将会调用实现了Runnable接口的run方法。上例中将会打印出”MyRunnable running”。

同样,也可以创建一个实现了Runnable接口的匿名类,如下所示:

Runnable myRunnable = new Runnable(){

public void run(){

System.out.println("Runnable running");

}

}

Thread thread = new Thread(myRunnable);

thread.start();

创建子类还是实现Runnable接口?

对于这两种方式哪种好并没有一个确定的答案,它们都能满足要求。就我个人意见,我更倾向于实现Runnable接口这种方法。因为线程池可以有效的管理实现了Runnable接口的线程,如果线程池满了,新的线程就会排队等候执行,直到线程池空闲出来为止。而如果线程是通过实现Thread子类实现的,这将会复杂一些。

有时我们要同时融合实现Runnable接口和Thread子类两种方式。例如,实现了Thread子类的实例可以执行多个实现了Runnable接口的线程。一个典型的应用就是线程池。

常见错误:调用run()方法而非start()方法

创建并运行一个线程所犯的常见错误是调用线程的run()方法而非start()方法,如下所示:

Thread newThread = new Thread(MyRunnable());

newThread.run(); //should be start();

起初你并不会感觉到有什么不妥,因为run()方法的确如你所愿的被调用了。但是,事实上,run()方法并非是由刚创建的新线程所执行的,而是被创建新线程的当前线程所执行了。也就是被执行上面两行代码的线程所执行的。想要让创建的新线程执行run()方法,必须调用新线程的start方法。

线程名

当创建一个线程的时候,可以给线程起一个名字。它有助于我们区分不同的线程。例如:如果有多个线程写入System.out,我们就能够通过线程名容易的找出是哪个线程正在输出。例子如下:

MyRunnable runnable = new MyRunnable();

Thread thread = new Thread(runnable, "New Thread");

thread.start();

System.out.println(thread.getName());

需要注意的是,因为MyRunnable并非Thread的子类,所以MyRunnable类并没有getName()方法。可以通过以下方式得到当前线程的引用:

Thread.currentThread();

因此,通过如下代码可以得到当前线程的名字:

String threadName = Thread.currentThread().getName();

线程代码举例:

这里是一个小小的例子。首先输出执行main()方法线程名字。这个线程JVM分配的。然后开启10个线程,命名为1~10。每个线程输出自己的名字后就退出。

public class ThreadExample {

public static void main(String[] args){

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

for(int i=0; i10; i++){

new Thread("" + i){

public void run(){

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

}

}.start();

}

}

}

需要注意的是,尽管启动线程的顺序是有序的,但是执行的顺序并非是有序的。也就是说,1号线程并不一定是第一个将自己名字输出到控制台的线程。这是因为线程是并行执行而非顺序的。Jvm和操作系统一起决定了线程的执行顺序,他和线程的启动顺序并非一定是一致的。

java集合 有序无序,线程是否安全

1.有序集合:集合里的元素可以根据key或index访问;无序集合:集合里的元素只能遍历。

有序集合在属性的增加,删除及修改中拥有较好的性能表现。

Set集合一般是无序的。实现hash算法的集合一般是无序的,例如hashMap,hashTable

List集合一般是有序的。

底层是Tree的一般是有序的,例如TreeSet,TreeMap

底层有lined的一般是有序的,它会用链表维护元素的顺序。

综上:

有序的:List的所有子类

无序的:一般的Set,除了TreeSet,linkedHashSet等底层是树或者链表的。一般的Map,除了底层是树或者链表的。

已知的线程安全集合:vector,hashtable,statck,enumeration

希望可以帮到你,谢谢!

java多个线程执行的顺序是按顺序执行的吗

这个要分段来实现, 第一步是让线程同步,第二部是让线程有顺序。

同步:我们可以用synchronized来解决。

Java线程同步原理: java会为每个object对象分配一个monitor,当某个对象的同步方法(synchronized methods )被多个线程调用时,该对象的monitor将负责处理这些访问的并发独占要求。

当一个线程调用一个对象的同步方法时,JVM会检查该对象的monitor。如果monitor没有被占用,那么这个线程就得到了monitor的占有权,可以继续执行该对象的同步方法;如果monitor被其他线程所占用,那么该线程将被挂起,直到monitor被释放。

当线程退出同步方法调用时,该线程会释放monitor,这将允许其他等待的线程获得monitor以使对同步方法的调用执行下去。就像下面这样:

public void test() {

synchronized (this) {

//做一些事

//这里只会有一个线程来调用该方法,因为只有一个this对象作为资源分配给该线程

}

}

顺序:我们可以用List来解决,因为它是有序的。我们只需要将要执行的线程放入到List中

上代码:

/**

* 让多个线程同步顺序执行的线程管理器

* @author bianrx

* @date 2012.1.18

* SynchronizedRunMultiThread

*/

public class SyncManager {

/**

* 待执行的线程集合,注意这里必须是Runnable接口类型,下面会解释

*/

private ListRunnable runnableList;

public SyncManager(){}

public SyncManager(ListRunnable runnableList) {

this.runnableList = runnableList;

}

public void setRunnable(ListRunnable runnableList) {

this.runnableList = runnableList;

}

public void run() {

//遍历代执行的线程集合

for(Runnable runnable: runnableList) {

runThread(runnable);

}

}

/**

* 按顺序同步执行多个线程

* @author bianrx

* @date 2012.1.18

* @param runnable

*/

private void runThread(Runnable runnable) {

synchronized (this) {

runnable.run();//这里需要注意的是:必须调用run方法,因为如果你调用了start方法,线程只会向JVM请求资源,但是未必就执行其中的run。

//这个方法是同步的,所以当前只有一个线程占用了this对象。

}

}

}

Java线程的概念与原理

一 操作系统中线程和进程的概念

现在的操作系统是多任务操作系统 多线程是实现多任务的一种方式

进程是指一个内存中运行的应用程序 每个进程都有自己独立的一块内存空间 一个进程中可以启动多个线程 比如在Windows系统中 一个运行的exe就是一个进程 线程是指进程中的一个执行流程 一个进程中可以运行多个线程 比如java exe进程中可以运行很多线程 线程总是属于某个进程 进程中的多个线程共享进程的内存 同时 执行是人的感觉 在线程之间实际上轮换执行

二 Java中的线程

在Java中 线程 指两件不同的事情

java lang Thread类的一个实例

线程的执行

使用java lang Thread类或者java lang Runnable接口编写代码来定义 实例化和启动新线程 一个Thread类实例只是一个对象 像Java中的任何其他对象一样 具有变量和方法 生死于堆上 Java中 每个线程都有一个调用栈 即使不在程序中创建任何新的线程 线程也在后台运行着 一个Java应用总是从main()方法开始运行 mian()方法运行在一个线程内 它被称为主线程 一旦创建一个新的线程 就产生一个新的调用栈 线程总体分两类 用户线程和守候线程

当所有用户线程执行完毕的时候 JVM自动关闭 但是守候线程却不独立于JVM 守候线程一般是由操作系统或者用户自己创建的

———————————MultiT java——————————————————————

class MultiThread

{

public static void main(String[] args)

{

MyThread mt=new MyThread();

//mt setDaemon(true);//设定为后台线程 main进程结束时 后台进程也跟着结束

//mt setPriority(Thread MAX_PRIORITY); //设定线程优先级 MAX_PRIORITY为 MIN_PRIORITY为 NORM_PRIORITY为

//设定为最高优先级后 程序运行时 mt线程一直运行 强制终止时 main线程才运行

//设定为最高优先级的线程 无论有无yield(); 线程总一直运行 直到强制终止时 main和mt线程交替运行

mt start();

int index= ;

while(true) //显示结果与教程不同

{

if(index++== )

break;

System out println( main: +Thread currentThread() getName()); //获取线程名字

}

}

}

class MyThread extends Thread

{

public void run()

{

while(true)

{

System out println(getName());

yield(); //允许当前线程停止 转去执行其他线程 静态方法

//mt进程执行时 切换到main进程 main进程执行一段时间后

//切换进程到mt mt执行完获取名字后 返回到main进程

}

}

}

//一个长时间处于等待状态的线程也有可能被线程调度器调度 从而运行

//打破高优先级线程始终获有运行时间的状态

——————————————————————————————————————

——————————MultiThread java———————————————————————

class MultiThread

{

public static void main(String[] args)

{

MyThread mt=new MyThread();

//new Thread(mt) start();   //创建多个同样的线程访问同一个变量index 若MyThread采用继承Thread方式 则无法共享同一个变量

//new Thread(mt) start();

//new Thread(mt) start();

//new Thread(mt) start();

mt getThread() start(); //也可以采用内部类的方式共享访问同一个变量

mt getThread() start();

mt getThread() start();

mt getThread() start();

//mt setDaemon(true);//设定为后台线程 main进程结束时 后台进程也跟着结束

//mt setPriority(Thread MAX_PRIORITY); //设定线程优先级 MAX_PRIORITY为 MIN_PRIORITY为 NORM_PRIORITY为

//设定为最高优先级后 程序运行时 mt线程一直运行 强制终止时 main线程才运行

//设定为最高优先级的线程 无论有无yield(); 线程总一直运行 直到强制终止时 main和mt线程交替运行

//mt start();

int index= ;

while(true) //显示结果与教程不同

{

// if(index++== )

//   break;

System out println( main: +Thread currentThread() getName()); //获取线程名字

}

}

}

class MyThread //implements Runnable //extends Thread //使用外部类的方式

//使用内部类完成使用Runnable接口才能完成的两个功能 a 创建多个线程 b 访问同一个变量

{

int index= ;

private class InnerThread extends Thread //不想让外部访问其实现方法 加上private

{

public void run()

{

while(true)

{

System out println(Thread currentThread() getName()+ : +index++);

}

}

}

Thread getThread()

{

return new InnerThread();

}

/*

public void run()

{

while(true)

{

System out println(Thread currentThread() getName()+ : +index++);

//yield(); //允许当前线程停止 转去执行其他线程 静态方法

//mt进程执行时 切换到main进程 main进程执行一段时间后

//切换进程到mt mt执行完获取名字后 返回到main进程

}

}

*/

}

//一个长时间处于等待状态的线程也有可能被线程调度器调度 从而运行

//打破高优先级线程始终获有运行时间的状态

//如果不需要修改Thread类的除了run方法外的其他方法 选用implements Runnable

———————————————————————————————————————

———————————TicketsSystem java———————————————————

//多线程实现火车票的售票系统 用同步块 或著同步方法

class TicketsSystem

{

public static void main(String[] args)    //运行结果与教程中不同 不完全顺序 每次运行 顺序都不完全一样

{

SellThread st=new SellThread();//创建四个线程访问同一变量tickets

// 错 SellThread st =new SellThread();//若采用创建四个对象的方式 则每个对象中都有 张票

new Thread(st) start();    //b为false 用的同步方法    | //同步方法与同步块共用中 显示的是只调用了同步块 而同步方法未被调用

//b为true 用的同步块      | //原因 启动第一个线程后 CPU时间片没有到期 线程没有立即运行 接着执行b=true

//               | //解决办法 启动第一个线程后 执行一个睡眠时间 让CPU时间片到期

try

{

Thread sleep( );

}

catch(Exception e)

{

e printStackTrace();

}

st b=true;

new Thread(st) start();

//new Thread(st) start();

//new Thread(st) start();

}

}

class SellThread implements Runnable   //程序有点小问题 当剩下最后一张票时 四个线程都运行 可能会出现票数为 (系统长时间运行时)

//可加上一个静态方法sleep();它会抛出异常

{

int tickets= ;

//Object obj=new Object();//也可以声明一个Thread对象

Thread th=new Thread();

boolean b=false;

public void run()

{

if(b==false)

{

while(true)

sell();

}

else

{

while(true)

{            //同步方法利用的是this所代表的对象的锁

synchronized(this) //采用同步后 显示正确 此方法两步 声明Thread对象 用synchronized把原方法括起来

{            //这里换th为this

///*

if(tickets )

{

try

{

Thread sleep( );

}

catch(Exception e)

{

e printStackTrace();

}

System out println( th +Thread currentThread() getName()+ sell tickets: +tickets);

tickets ;

}

//*/

}

}

}

}

public synchronized void sell() //每个class也有一个锁 是这个class所对应的class对象的锁(监视器)

{

if(tickets )

{

try

{

Thread sleep( );

}

catch(Exception e)

{

e printStackTrace();

}

System out println( sell +Thread currentThread() getName()+ sell tickets: +tickets);

tickets ;

}

}

}

————————————————————————————————————————

———————————TestWN java————————————————————

class Test

{

public static void main(String[] args)

{

Queue q=new Queue();

Producer p=new Producer(q);

Consumer c=new Consumer(q);

p start();

c start();

}

}

class Producer extends Thread

{

Queue q;

Producer(Queue q)

{

this q=q;

}

public void run()

{

for(int i= ;i ;i++)

{

q put(i);

System out println( Producer put: +i);

}

}

}

class Consumer extends Thread

{

Queue q;

Consumer(Queue q)

{

this q=q;

}

public void run()

{

while(true)

{

System out println( Consumer get: +q get());

}

}

}

class Queue   //wait notify 方法必须用在同步方法中 要加上关键字synchronized

{

int value;

boolean bFull=false;

public synchronized void put(int i)

{

if(!bFull)

{

value=i;

bFull=true;

notify();

}

try

{

wait();

}

catch(Exception e)

{

e printStackTrace();

}

}

public synchronized int get()

{

if(!bFull)

{

try

{

wait();

}

catch(Exception e)

{

e printStackTrace();

}

}

bFull=false;

notify();

return value;

}

}

————————————————————————————————————

————————————TestThread java———————————————————————

class TestThread

{

public static void main(String[] args)

{

Thread t =new Thread ();

t start();

int index= ;

while(true)

{

if(index++== )

{

t stopThread();

t interrupt(); //让线程 终止

break;

}

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

}

System out println( main() exit );

}

}

class Thread extends Thread

{

private boolean bStop=false;

public synchronized void run()

{

while(!bStop)

{

try

{

wait(); //加入wait后 main线程结束时 程序还未终止 原因是Thread 的线程调用wait方法 进入对象的等待队列中 需要notify方法将它唤醒

}

catch(Exception e)

{

//e printStackTrace();

if(bStop)

return;

}

System out println(getName());

}

}

public void stopThread()

{

bStop=true;

}

}

lishixinzhi/Article/program/Java/gj/201311/27407

用Java线程编写三个线程,按顺序输出线程。。。

设置了线程优先级的作用是,让JVM能够多分配内存空间执行此线程,也就是说此线程如果优先级高于其他线程,会比其他线程执行的次数多,而不是顺序靠前

JAVA中如何保证线程安全以及主键自增有序

一、常见场景 多个线程针对一个i进行主键自增。多线程下如果不做安全策略,将会导致各个现成获取的i值重复,导致脏数据常见策略1、增加syschroize进行线程同步 2、使用lock、unlock处理 3、使用reetrantent 锁进行锁定 缺点:容易造成性能低下,或者编写代码容易造成死锁二、新方案jdk新提供的功能,atomicInteger(还有其他一atomic开头的原子性操作类) AtomicInteger,一个提供原子操作的Integer的类。在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口。 原理:通过java的CAS compare and swap,简称cas原语进行操作提升性能,这个也号称乐观锁,不阻塞 观锁实际上并不加锁,当计算遇到冲突或者说前后不一致时会重试 直到成功 CAS有3个操作数 内存值V 要跟内存值做比较的值A 和 新值 B while(true){ if(V == A){V = B;return ;}else{A = V;}}CAS的操作对象为volatile类型 volatile类型变量是:CPU直接读写变量所在的内存 而不是把变量copy到寄存器操作 这样对变量的操作所有线程都是可见的这样做的结果是减少了并发时冲突的概率 但不能完全避免

关于java有序线程和java产生线程的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。