「java跨线程」java跨线程和跨类更新ui

博主:adminadmin 2022-11-28 14:56:07 42

今天给各位分享java跨线程的知识,其中也会对java跨线程和跨类更新ui进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

在Java 中多线程的实现方法有哪些,如何使用

1、 认识Thread和Runnable

Java中实现多线程有两种途径:继承Thread类或者实现Runnable接口。Runnable是接口,建议用接口的方式生成线程,因为接口可以实现多继承,况且Runnable只有一个run方法,很适合继承。在使用Thread的时候只需继承Thread,并且new一个实例出来,调用start()方法即可以启动一个线程。

Thread Test = new Thread();

Test.start();

在使用Runnable的时候需要先new一个实现Runnable的实例,之后启动Thread即可。

Test impelements Runnable;

Test t = new Test();

Thread test = new Thread(t);

test.start();

总结:Thread和Runnable是实现java多线程的2种方式,runable是接口,thread是类,建议使用runable实现java多线程,不管如何,最终都需要通过thread.start()来使线程处于可运行状态。

2、 认识Thread的start和run

1) start:

用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到spu时间片,就开始执行run()方法,这里方法run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止。

2) run:

run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。

总结:调用start方法方可启动线程,而run方法只是thread的一个普通方法调用,还是在主线程里执行。

3、 线程状态说明

线程状态从大的方面来说,可归结为:初始状态、可运行状态、不可运行状态和消亡状态,具体可细分为上图所示7个状态,说明如下:

1) 线程的实现有两种方式,一是继承Thread类,二是实现Runnable接口,但不管怎样,当我们new了thread实例后,线程就进入了初始状态;

2) 当该对象调用了start()方法,就进入可运行状态;

3) 进入可运行状态后,当该对象被操作系统选中,获得CPU时间片就会进入运行状态;

4) 进入运行状态后case就比较多,大致有如下情形:

·run()方法或main()方法结束后,线程就进入终止状态;

·当线程调用了自身的sleep()方法或其他线程的join()方法,就会进入阻塞状态(该状态既停止当前线程,但并不释放所占有的资源)。当sleep()结束或join()结束后,该线程进入可运行状态,继续等待OS分配时间片;

·当线程刚进入可运行状态(注意,还没运行),发现将要调用的资源被锁牢(synchroniza,lock),将会立即进入锁池状态,等待获取锁标记(这时的锁池里也许已经有了其他线程在等待获取锁标记,这时它们处于队列状态,既先到先得),一旦线程获得锁标记后,就转入可运行状态,等待OS分配CPU时间片;

·当线程调用wait()方法后会进入等待队列(进入这个状态会释放所占有的所有资源,与阻塞状态不同),进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒(由于notify()只是唤醒一个线程,但我们由不能确定具体唤醒的是哪一个线程,也许我们需要唤醒的线程不能够被唤醒,因此在实际使用时,一般都用notifyAll()方法,唤醒有所线程),线程被唤醒后会进入锁池,等待获取锁标记。

·当线程调用stop方法,即可使线程进入消亡状态,但是由于stop方法是不安全的,不鼓励使用,大家可以通过run方法里的条件变通实现线程的stop。

Java 实现多线程的几种方式汇总

有三种:

(1)继承Thread类,重写run函数

创建:

class xx extends Thread{

public void run(){

Thread.sleep(1000) //线程休眠1000毫秒,sleep使线程进入Block状态,并释放资源

}}

开启线程:

对象.start() //启动线程,run函数运行

(2)实现Runnable接口,重写run函数

开启线程:

Thread t = new Thread(对象) //创建线程对象

t.start()

(3)实现Callable接口,重写call函数

Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。

Callable和Runnable有几点不同:

①Callable规定的方法是call(),而Runnable规定的方法是run().

②Callable的任务执行后可返回值,而Runnable的任务是不能返回值的

③call()方法可抛出异常,而run()方法是不能抛出异常的。

④运行Callable任务可拿到一个Future对象,Future表示异步计算的结果。它提供了检查计算是否完成的方法,以等

待计算的完成,并检索计算的结果.通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果

java两个线程之间如何实现切换

仔细看看30 60关键点,跟sleep时间长短有关,短了可能来不及执行又换另一线程

public class Test extends Thread {

public static void main(String[] args){

new Test().start();

new Test().start();

new Test().start();

}

public void run(){

try{

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

System.out.println(getName()+":"+i);

if(i==30){

sleep(100);

}

if(i==60){

sleep(100);

}

}

}catch(Exception e){}

}

}

求JAVA跨线程访问组件的实现

1,把你要访问的对象作为参数放到新线程的构造里去

2,使用管道流在两个线程间进行通讯

可能还有别的

不管怎样都要注意线程同步和对象锁

如何让Java以光的速度跨线程通信

一个比Disruptor吞吐量等性能指标更好的框架,使用Railway算法,将线程之间的消费发送参考现实生活中火车在站点之间搬运货物。

目标起始于一个简单的想法:创建一个开发人员友好的,简单的,轻量级线程间的通信框架,无需使用任何锁,同步器,信号量,等待,通知以及没有队列,消息,事件或任何其它并发特定的语法或工具。

只是一个Java接口接受到POJO以后在其背后实现这个通信,这个主意很类似Akka的Actors,但是它也许是有点矫枉过正,特别是对于单个多核计算机上线程间的通信优化必须是轻量的。

Akka的伟大之处是跨进程通信,特别是Actor是能够跨越不同JVM节点实现分布式通信。

无论如何,你可能觉得使用Akka在一个小型项目上有些过度,因为你只需要线程之间的通信,但是你还是想使用类似Actor这种做法模式。

该文章作者使用了动态代理 堵塞队列和一个缓存的线程池创建了这个解决方案,如图:

SPSC队列是一个Single Producer/Single Consumer 队列(单生产者/单消费者),而MPSC是一个Multi Producer/Single Consumer队列。

Dispatcher线程从Actor线程接受到消息,然后发送到相应的SPSC中。

Actor线程从接受的消息中使用数据,调用相应的actor类的方法,Actor实例都是发送消息给MPSC队列,然后再从Actor线程那里得到消息。

下面是ping-pong案例:

public interface PlayerA (

void pong(long ball); //send and forget method call

}

public interface PlayerB {

void ping(PlayerA playerA, long ball); //send and forget method call

}

public class PlayerAImpl implements PlayerA {

@Override

@ublic void pong(long ball) {

}

}

public class PlayerBImpl implements PlayerB {

@Override

public void ping(PlayerA playerA, long ball) {

playerA.pong(ball);

}

}

public class PingPongExample {

public void testPingPong() {

// this manager hides the complexity of inter-thread communications

// and it takes control over actor proxies, actor implementations and threads

ActorManager manager = new ActorManager();

// registers actor implementations inside the manager

manager.registerImpl(PlayerAImpl.class);

manager.registerImpl(PlayerBImpl.class);

//Create actor proxies. Proxies convert method calls into internal messages

//which would be sent between threads to a specific actor instance.

PlayerA playerA = manager.createActor(PlayerA.class);

PlayerB playerB = manager.createActor(PlayerB.class);

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

playerB.ping(playerA, i);

}

}

这两个play能够每秒打500,000个乒乓。但是如果和单个线程执行速度相比,还是很差的,同样代码在单个线程可以到达每秒两百万个。

作者开始研究缓慢的原因,在一些校验和测试以后,他认为是Actors之间发送消息影响了整体性能:

作者找到一个SPSC单生产者和单消费者的无锁队列,

无锁队列提供比锁队列更好的性能。锁队列中在当一个线程获得锁,其他线程将被阻塞,直到该锁被释放的。在无锁算法的情况下,生产者线程可以产生消息,但不阻止其他生产者线程,以及其他消费者,而从队列中读取的消费者不会被阻塞。

这个无锁队列据测试结果是超过每秒100M ops,是JDK的并发队列实现的10倍。

但是作者使用这个无锁队列提到SPSC 以后,并没有产生明显性能提升,他立即意识到这个框架的性能瓶颈不是在SPSC,而是在多个生产者/单个消费者(MPSC)那里。

多个生产者如果使用SPSC会覆盖彼此的值,因为SPSC并没有一个对生产者的控制机制,即使最快的SPSC也不适合。

对于MPSC作者找到了LMAX的disruptor,一个通过Ringbuffer实现的高性能线程间通信库包。

使用Disruptor很容易实现非常低延迟,高吞吐量的线程间消息通信。它还提供了用例对生产者和消费者的不同组合。多个线程可以从环形缓冲区中读取而不会阻塞对方:

多生产者和多消费者:

三个生产者/一个消费者测试结果显示,Disruptor都是两倍于LinkedBlockingQueue 。

但是使用Disruptor后的这个框架性能还是没有达到预期,作者从上下班的地铁中得到灵感,在某个站点同一车厢出来的人是生产者,进去的是消费者。

建立一个Railway类,使用AtomicLong来跟踪地铁在站与站之间的传递,下面是一个single-train railway:

public class RailWay {

private final Train train = new Train();

//站台号码stationNo 跟踪火车,定义哪个站点接受火车

private final AtomicInteger stationIndex = new AtomicInteger();

//多线程访问这个方法,也就是在特定站点等待火车

public Train waitTrainOnStation(final int stationNo) {

while (stationIndex.get() % stationCount != stationNo) {

Thread.yield(); // this is necessary to keep a high throughput of message passing.

//But it eats CPU cycles while waiting for a train

}

// the busy loop returns only when the station number will match

// stationIndex.get() % stationCount condition

return train;

}

//这个方法通过增加火车站台号将火车移到下一个站点。 public void sendTrain() {

stationIndex.getAndIncrement();

}

}

参考Disruptor,创建线程间传递long值:

public class Train {

//

public static int CAPACITY = 2*1024;

private final long[] goodsArray; // array to transfer freight goods

private int index;

public Train() {

goodsArray = new long[CAPACITY];

}

public int goodsCount() { // returns the count of goods

return index;

}

public void addGoods(long i) { // adds item to the train

goodsArray[index++] = i;

}

public long getGoods(int i) { //removes the item from the train

index--;

return goodsArray[i];

}

}

如下图两个线程传递long:

使用一列火车实现单个生产者单个消费者:

public void testRailWay() {

final Railway railway = new Railway();

final long n = 20000000000l;

//starting a consumer thread

new Thread() {

long lastValue = 0;

@Override

public void run() {

while (lastValue n) {

Train train = railway.waitTrainOnStation(1); //waits for the train at the station #1

int count = train.goodsCount();

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

lastValue = train.getGoods(i); // unload goods

}

railway.sendTrain(); //sends the current train to the first station.

}

}

}.start();

final long start = System.nanoTime();

long i = 0;

while (i n) {

Train train = railway.waitTrainOnStation(0); // waits for the train on the station #0

int capacity = train.getCapacity();

for (int j = 0; j capacity; j++) {

train.addGoods((int)i++); // adds goods to the train

}

railway.sendTrain();

if (i % 100000000 == 0) { //measures the performance per each 100M items

final long duration = System.nanoTime() - start;|

final long ops = (i * 1000L * 1000L * 1000L) / duration;

System.out.format("ops/sec = %,d\n", ops);

System.out.format("trains/sec = %,d\n", ops / Train.CAPACITY);

System.out.format("latency nanos = %.3f%n\n",

duration / (float)(i) * (float) Train.CAPACITY);

}

}

}

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

The End

发布于:2022-11-28,除非注明,否则均为首码项目网原创文章,转载请注明出处。